apache/hadoop · error · IOException

SAXTransformer error: {}

Error message

SAXTransformer error: {}

What it means

XmlEditsVisitor serializes edit-log ops to XML through a JAXP SAXTransformerFactory/TransformerHandler pipeline. This IOException wraps a TransformerConfigurationException raised while obtaining or configuring the handler in the constructor (newTransformerHandler plus output properties). It is an environment problem — the JVM's XML transformer could not be instantiated — not an edits-data problem.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/tools/offlineEditsViewer/XmlEditsVisitor.java:78

  public XmlEditsVisitor(OutputStream out)
      throws IOException {
    this.out = out;
    try {
      factory = org.apache.hadoop.util.XMLUtils.newSecureSAXTransformerFactory();
      TransformerHandler handler = factory.newTransformerHandler();
      handler.getTransformer().setOutputProperty(OutputKeys.METHOD, "xml");
      handler.getTransformer().setOutputProperty(OutputKeys.ENCODING, "UTF-8");
      handler.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes");
      handler.getTransformer().setOutputProperty(XML_INDENTATION_PROP,
              XML_INDENTATION_NUM);
      handler.getTransformer().setOutputProperty(OutputKeys.STANDALONE, "yes");
      handler.setResult(new StreamResult(out));
      contentHandler = handler;
      
      contentHandler.startDocument();
      contentHandler.startElement("", "", "EDITS", new AttributesImpl());
    } catch (TransformerConfigurationException e) {
      throw new IOException("SAXTransformer error: " + e.getMessage());
    } catch (SAXException e) {
      throw new IOException("SAX error: " + e.getMessage());
    }
  }

  /**
   * Start visitor (initialization)
   */
  @Override
  public void start(int version) throws IOException {
    try {
      contentHandler.startElement("", "", "EDITS_VERSION", new AttributesImpl());
      StringBuilder bld = new StringBuilder();
      bld.append(version);
      addString(bld.toString());
      contentHandler.endElement("", "", "EDITS_VERSION");
    }
    catch (SAXException e) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Check for overrides: print System.getProperty("javax.xml.transform.TransformerFactory") — it should be null (JDK default) or a known-good factory.
  2. Prune duplicate/old xalan, xercesImpl and xml-apis jars from the classpath so the JDK implementation wins.
  3. If a specific factory must be set, verify it supports SAXTransformerFactory.FEATURE and newTransformerHandler() before launching.
  4. Reproduce on a stock JDK with a minimal classpath (just the hadoop jars) to confirm the environment is the cause.

Example fix

# before
export JAVA_TOOL_OPTIONS="-Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.TransformerFactoryImpl"
hdfs oev -i edits -p XML -o out.xml   # old xalan on classpath

# after
unset JAVA_TOOL_OPTIONS
hdfs oev -i edits -p XML -o out.xml   # JDK default transformer
Defensive patterns

Strategy: try-catch

Validate before calling

import javax.xml.transform.*;

private static void verifyTransformerFactory() throws IOException {
  try {
    SAXTransformerFactory f = (SAXTransformerFactory) TransformerFactory.newInstance();
    if (!f.getFeature(SAXTransformerFactory.FEATURE)) {
      throw new IOException("Configured TransformerFactory cannot serialize SAX");
    }
    f.newTransformerHandler();  // fail fast with a clear message
  } catch (ClassCastException | TransformerConfigurationException e) {
    throw new IOException("Bad JAXP setup: check -Djavax.xml.transform.TransformerFactory and classpath", e);
  }
}

Try / catch

try {
  visitor = new XmlEditsVisitor(out);
} catch (IOException e) {
  if (e.getMessage().startsWith("SAXTransformer error")) {
    // environment: fix JAXP factory/classpath instead of retrying
    throw new IllegalStateException("XML transformer misconfigured: " + e.getMessage(), e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Constructing XmlEditsVisitor when javax.xml.transform.TransformerFactory (system property or META-INF/services) resolves to an implementation that cannot supply a TransformerHandler or rejects the requested output properties. Typically conflicting or ancient xalan/xerces jars ahead of the JDK's built-in implementation.

Common situations: Launchers that set -Djavax.xml.transform.TransformerFactory=...; applications embedding Hadoop that bundle an old xalan.jar; hardened JVMs or agents that restrict transformer instantiation; unusual JREs without a default transformer.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/6a3fcc4531bcf7f7. Report an issue: GitHub.