pentaho/pentaho-kettle · error · SAXException
Invalid Transformation - Missing…
Error message
Invalid Transformation - Missing transformation_configuration tag
What it means
RegisterTransServlet.validateTransformation parses the posted XML and throws SAXException if the root element is not 'transformation_configuration'. The upload must be a full transformation configuration export, not a bare .ktr document.
Solutions
- Post the full transformation_configuration export XML (as generated by the export endpoint), not a plain .ktr.
- Verify the request body actually contains XML (check for empty body or HTML error responses from upstream).
- Validate the root element locally before uploading: parse and check documentElement name equals 'transformation_configuration'.
- Ensure the client sets Content-Type application/xml and sends the complete body.
Example fix
// before
byte[] body = Files.readAllBytes(Paths.get("trans.ktr")); // root: <transformation>
post("/kettle/registerTrans/", body);
// after
byte[] body = Files.readAllBytes(Paths.get("transformation_configuration.xml")); // root: <transformation_configuration>
post("/kettle/registerTrans/", body, "application/xml"); Defensive patterns
Strategy: validation
Validate before calling
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.ByteArrayInputStream;
boolean isTransformationConfiguration(byte[] body) throws Exception {
DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
df.setFeature("http://xml.org/sax/features/external-general-entities", false);
Document doc = df.newDocumentBuilder().parse(new ByteArrayInputStream(body));
return doc.getDocumentElement().getNodeName().equals("transformation_configuration");
} Try / catch
try {
post("/kettle/registerTrans/", body, "application/xml");
} catch (BadRequestException e) {
// server rejected: body root is not transformation_configuration
log.error("Upload must be a transformation configuration export, not a plain .ktr");
} Prevention
- Always upload configuration exports (exported via the export servlet), never raw .ktr files.
- Assert Content-Type is application/xml; reject HTML error pages before forwarding.
- Check the body is non-empty and starts with '<?xml' before upload.
- Validate root element name client-side pre-upload.
When it happens
Trigger: POST /kettle/registerTrans/ with a body whose XML root tag is something other than <transformation_configuration> — e.g. a plain <transformation> file, HTML error page, or truncated upload.
Common situations: Users posting a plain transformation.ktr instead of the configuration export produced by ExportTransServlet; a proxy returning an HTML error page that gets posted onward; empty/truncated request body.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid Transformation - Missing…
- Invalid Transformation Name
- Invalid Transformation Name
- ERROR: There was an error opening the file, since the…
- GetJobStatusServlet.Error.UnableToGetJobStatusInXML
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/595f2cdab499ad46.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/www/RegisterTransServlet.java:82
return new WebResult( WebResult.STRING_OK, message, trans.getContainerObjectId() );
} catch ( KettleXMLException | SAXException ex ) {
response.setStatus( HttpServletResponse.SC_BAD_REQUEST );
return new WebResult( WebResult.STRING_ERROR, ex.getMessage(), "" );
} catch ( Exception ex ) {
response.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
return new WebResult( WebResult.STRING_ERROR, ex.getMessage(), "" );
}
}
public void validateTransformation( InputStream is ) throws IOException, ParserConfigurationException, SAXException,
XPathExpressionException {
DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
df.setFeature( "http://xml.org/sax/features/external-general-entities", false );
df.setFeature( "http://xml.org/sax/features/external-parameter-entities", false );
DocumentBuilder builder = df.newDocumentBuilder();
Document doc = builder.parse( is );
if ( !doc.getDocumentElement().getNodeName().equals( "transformation_configuration" ) ) {
throw new SAXException( "Invalid Transformation - Missing transformation_configuration tag" );
}
XPath xPath = XPathFactory.newInstance().newXPath();
Node node = (Node) xPath.evaluate( "/transformation_configuration/transformation/info/name", doc, XPathConstants.NODE );
if ( node == null || node.getChildNodes().getLength() > 1 || !( node.getFirstChild() instanceof DeferredTextImpl ) ) {
throw new SAXException( "Invalid Transformation Name" );
}
}
}
View on GitHub (pinned to f3058517a1)