quarkusio/quarkus · error · PSQLException

UNEXPECTED_ERROR

UNEXPECTED_ERROR

Error message

Unable to create SAXResult for SQLXML.

What it means

PgSQLXML is Quarkus's native-image substitute for PostgreSQL's SQLXML. When creating a javax.xml.transform.sax.SAXResult via setResult(Class), the underlying TransformerHandler must accept a TransformerHandler.setResult(StreamResult) call; if the transformer factory throws a TransformerException during that setup, this PSQLException with SQLState UNEXPECTED_ERROR is thrown. It means the JAXP SAX transformer pipeline could not be configured, usually a missing/broken XML transformer implementation in the runtime image.

Source

Thrown at extensions/jdbc/jdbc-postgresql/runtime/src/main/java/io/quarkus/jdbc/postgresql/runtime/graal/PgSQLXML.java:245

    public synchronized <T extends Result> T setResult(Class<T> resultClass) throws SQLException {
        checkFreed();
        initialize();

        if (resultClass == null || DOMResult.class.equals(resultClass)) {
            domResult = new DOMResult();
            active = true;
            //noinspection unchecked
            return (T) domResult;
        } else if (SAXResult.class.equals(resultClass)) {
            try {
                SAXTransformerFactory transformerFactory = getXmlFactoryFactory().newSAXTransformerFactory();
                TransformerHandler transformerHandler = transformerFactory.newTransformerHandler();
                stringWriter = new StringWriter();
                transformerHandler.setResult(new StreamResult(stringWriter));
                active = true;
                return resultClass.cast(new SAXResult(transformerHandler));
            } catch (TransformerException te) {
                throw new PSQLException(GT.tr("Unable to create SAXResult for SQLXML."),
                        PSQLState.UNEXPECTED_ERROR, te);
            }
        } else if (StreamResult.class.equals(resultClass)) {
            stringWriter = new StringWriter();
            active = true;
            return resultClass.cast(new StreamResult(stringWriter));
        } else if (StAXResult.class.equals(resultClass)) {
            StringWriter stringWriter = new StringWriter();
            this.stringWriter = stringWriter;
            try {
                XMLOutputFactory xof = getXmlFactoryFactory().newXMLOutputFactory();
                XMLStreamWriter xsw = xof.createXMLStreamWriter(stringWriter);
                active = true;
                return resultClass.cast(new StAXResult(xsw));
            } catch (XMLStreamException xse) {
                throw new PSQLException(GT.tr("Unable to create StAXResult for SQLXML"),
                        PSQLState.UNEXPECTED_ERROR, xse);
            }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Check for XML-related GraalVM/JAXP provider issues: ensure a working TransformerFactory (Xalan/internal) is included in the native image and its service files are registered
  2. Log the chained TransformerException (getCause()) to see the real provider failure and fix the underlying factory configuration
  3. As a workaround, use setResult(StreamResult.class) or setResult(DOMResult.class), which do not go through the TransformerHandler path
  4. Test the same XML write path in JVM mode to confirm whether it is native-image specific

Example fix

// before
SAXResult r = sqlxml.setResult(SAXResult.class);
Transformer t = r.getTransformer();
// after (avoid TransformerHandler path)
StreamResult r = sqlxml.setResult(StreamResult.class);
Transformer t = tFactory.newTransformer();
t.transform(new DOMSource(node), r);
Defensive patterns

Strategy: try-catch

Validate before calling

// Sanity-check the transformer provider before using SAXResult with SQLXML
TransformerFactory tf = TransformerFactory.newInstance();
try { tf.newTransformerHandler(); } catch (TransformerException e) {
    throw new IllegalStateException("No working TransformerHandler provider", e);
}

Try / catch

try {
    SAXResult r = sqlxml.setResult(SAXResult.class);
} catch (SQLException e) {
    if ("08000".equals(e.getSQLState()) || e.getCause() instanceof TransformerException) {
        // fall back to StreamResult path
        StreamResult sr = sqlxml2.setResult(StreamResult.class);
    } else throw e;
}

Prevention

When it happens

Trigger: Calling resultSet.getSQLXML(...).setResult(SAXResult.class) (or an XML getSource(SAXResult.class) write path) where transformerFactory.newTransformerHandler() succeeded but transformerHandler.setResult(new StreamResult(...)) throws TransformerException (e.g. missing XML parser/transformer provider, bad system configuration).

Common situations: Native-image builds lacking a TransformerHandler implementation or XML factory service files; restrictive javax.xml.transform.TransformerFactory configuration via system properties; classpath conflicts providing a broken TransformerFactory in native mode.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/8eb72b1b18419673. Report an issue: GitHub.