{"record":{"id":"2050b4948e075bd2","repo":"pentaho/pentaho-kettle","slug":"invalid-transformation-missing-transformation-configuration","errorCode":null,"errorMessage":"Invalid Transformation - Missing transformation_configuration tag","messagePattern":"Invalid Transformation - Missing transformation_configuration tag","errorType":"http","errorClass":"SAXException","httpStatus":500,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/www/AddTransServlet.java","lineNumber":351,"sourceCode":"  }\n\n  public String getService() {\n    return CONTEXT_PATH + \" (\" + toString() + \")\";\n  }\n\n  public String getContextPath() {\n    return CONTEXT_PATH;\n  }\n\n  public void validateTransformation( InputStream is ) throws IOException, ParserConfigurationException, SAXException,\n    XPathExpressionException {\n    DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();\n    df.setFeature( \"http://xml.org/sax/features/external-general-entities\", false );\n    df.setFeature( \"http://xml.org/sax/features/external-parameter-entities\", false );\n    DocumentBuilder builder = df.newDocumentBuilder();\n    Document doc = builder.parse( is );\n    if ( !doc.getDocumentElement().getNodeName().equals( \"transformation_configuration\" ) ) {\n      throw new SAXException( \"Invalid Transformation - Missing transformation_configuration tag\" );\n    }\n    XPath xPath = XPathFactory.newInstance().newXPath();\n    Node node = (Node) xPath.evaluate( \"/transformation_configuration/transformation/info/name\", doc, XPathConstants.NODE );\n    if ( node == null  || node.getChildNodes().getLength() > 1 || !( node.getFirstChild() instanceof DeferredTextImpl ) ) {\n      throw new SAXException( \"Invalid Transformation Name\" );\n    }\n  }\n}\n","sourceCodeStart":333,"sourceCodeEnd":360,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/www/AddTransServlet.java#L333-L360","documentation":"AddTransServlet.validateTransformation throws this SAXException when the uploaded XML payload's root element is not <transformation_configuration>. The servlet rejects the request before parsing the transformation, because the expected configuration envelope tag is missing.","triggerScenarios":"POSTing to /kettle/addTrans/ with an XML body whose root element is something other than 'transformation_configuration' — e.g. uploading a raw .ktr (root <transformation>) or an execution-info XML instead of the required wrapper.","commonSituations":"Calling the Carte REST API and uploading transformation.xml directly instead of a transformation_configuration wrapper; using an old client/SDK that predates the transformation_configuration envelope; template copy-paste errors in scripted Carte uploads.","solutions":["Wrap the <transformation> XML inside a <transformation_configuration> root element before uploading.","Check the client/API version — use the envelope format expected by your Pentaho/Carte version.","Verify the first bytes of the POST body actually contain the correct root tag (no BOM/whitespace-prefix issues from a different doctype).","Use a known-good sample request body from the Carte 'Add Trans' documentation as a template."],"exampleFix":"// before: uploading raw transformation XML\nInputStream is = new FileInputStream(\"trans.ktr\"); // root: <transformation>\n// after: wrap it\nString xml = \"<transformation_configuration>\"\n  + new String(Files.readAllBytes(Paths.get(\"trans.ktr\")), StandardCharsets.UTF_8)\n  + \"</transformation_configuration>\";\nInputStream is = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));","handlingStrategy":"validation","validationCode":"String body = new String(Files.readAllBytes(path), StandardCharsets.UTF_8).trim();\nif (!body.startsWith(\"<transformation_configuration\")) {\n    throw new IllegalArgumentException(\"Root must be transformation_configuration\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    postToAddTrans(xmlBody);\n} catch (SAXException e) {\n    if (e.getMessage().contains(\"transformation_configuration\")) { /* fix envelope and re-post */ }\n    throw e;\n}","preventionTips":["Always wrap <transformation> in <transformation_configuration> for addTrans uploads.","Keep a canonical sample request body for the Carte API version in use.","Lint generated XML against the expected root element before sending."],"tags":["xml","servlet","validation","carte","rest"],"backgroundTag":"schema-validation-failed","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}