diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index d75f765de0..311de91110 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -1837,16 +1837,36 @@ xml_parse(text *data, XmlOptionType xmloption_arg,
 			/* allow empty content */
 			if (*(utf8string + count))
 			{
+				xmlNodePtr	node_list = NULL;
+
 				res_code = xmlParseBalancedChunkMemory(doc, NULL, NULL, 0,
 													   utf8string + count,
-													   parsed_nodes);
+													   &node_list);
+
+				/*
+				 * libxml2 2.13.x incorrectly returns parser errors even if
+				 * the chunk is well-balanced.  As a workaround, ignore the
+				 * return code if a node list was returned.
+				 * https://gitlab.gnome.org/GNOME/libxml2/-/issues/765
+				 */
+#if LIBXML_VERSION >= 21300
+				if (res_code > 0 && node_list != NULL)
+					res_code = 0;
+#endif
+
 				if (res_code != 0 || xmlerrcxt->err_occurred)
 				{
+					xmlFreeNodeList(node_list);
 					xml_errsave(escontext, xmlerrcxt,
 								ERRCODE_INVALID_XML_CONTENT,
 								"invalid XML content");
 					goto fail;
 				}
+
+				if (parsed_nodes != NULL)
+					*parsed_nodes = node_list;
+				else
+					xmlFreeNodeList(node_list);
 			}
 		}
 
