diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index f3db3f075481e8e1872d0ae13759ca7b9a8b2135..99b978c42c08089f3675f6e675f419b2c935a3ae 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -928,6 +928,7 @@ PgXmlErrorContext *
 pg_xml_init(PgXmlStrictness strictness)
 {
 	PgXmlErrorContext *errcxt;
+	void	   *new_errcxt;
 
 	/* Do one-time setup if needed */
 	pg_xml_init_library();
@@ -956,6 +957,34 @@ pg_xml_init(PgXmlStrictness strictness)
 
 	xmlSetStructuredErrorFunc((void *) errcxt, xml_errorHandler);
 
+	/*
+	 * Verify that xmlSetStructuredErrorFunc set the context variable we
+	 * expected it to.  If not, the error context pointer we just saved is not
+	 * the correct thing to restore, and since that leaves us without a way to
+	 * restore the context in pg_xml_done, we must fail.
+	 *
+	 * The only known situation in which this test fails is if we compile with
+	 * headers from a libxml2 that doesn't track the structured error context
+	 * separately (<= 2.7.3), but at runtime use a version that does, or vice
+	 * versa.  The libxml2 authors did not treat that change as constituting
+	 * an ABI break, so the LIBXML_TEST_VERSION test in pg_xml_init_library
+	 * fails to protect us from this.
+	 */
+
+#ifdef HAVE_XMLSTRUCTUREDERRORCONTEXT
+	new_errcxt = xmlStructuredErrorContext;
+#else
+	new_errcxt = xmlGenericErrorContext;
+#endif
+
+	if (new_errcxt != (void *) errcxt)
+		ereport(ERROR,
+				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+				 errmsg("could not set up XML error handler"),
+				 errhint("This probably indicates that the version of libxml2"
+						 " being used is not compatible with the libxml2"
+						 " header files that PostgreSQL was built with.")));
+
 	return errcxt;
 }
 
@@ -1494,9 +1523,14 @@ xml_errorHandler(void *data, xmlErrorPtr error)
 	int			level = error->level;
 	StringInfo	errorBuf;
 
-	/* Defend against someone passing us a bogus context struct */
+	/*
+	 * Defend against someone passing us a bogus context struct.
+	 *
+	 * We force a backend exit if this check fails because longjmp'ing out of
+	 * libxml would likely render it unsafe to use further.
+	 */
 	if (xmlerrcxt->magic != ERRCXT_MAGIC)
-		elog(ERROR, "xml_errorHandler called with invalid PgXmlErrorContext");
+		elog(FATAL, "xml_errorHandler called with invalid PgXmlErrorContext");
 
 	/*----------
 	 * Older libxml versions report some errors differently.