{"record":{"id":"e221dfb0567b74df","repo":"pentaho/pentaho-kettle","slug":"jobmeta-exception-errorreadingfromxmlfile","errorCode":null,"errorMessage":"JobMeta.Exception.ErrorReadingFromXMLFile","messagePattern":"JobMeta\\.Exception\\.ErrorReadingFromXMLFile","errorType":"exception","errorClass":"KettleXMLException","httpStatus":null,"severity":"error","filePath":"engine/src/main/java/org/pentaho/di/job/JobMeta.java","lineNumber":885,"sourceCode":"   * @param fname The filename to load as a job\n   * @param rep   The repository to bind againt, null if there is no repository available.\n   * @throws KettleXMLException\n   */\n  public JobMeta( Bowl bowl, VariableSpace parentSpace, String fname, Repository rep, IMetaStore metaStore,\n      OverwritePrompter prompter ) throws KettleXMLException {\n    this.initializeVariablesFrom( parentSpace );\n    this.metaStore = metaStore;\n    setBowl( bowl );\n    try {\n      // OK, try to load using the VFS stuff...\n      Document doc = XMLHandler.loadXMLFile( KettleVFS.getInstance( bowl ).getFileObject( fname, this ) );\n      if ( doc != null ) {\n        // The jobnode\n        Node jobnode = XMLHandler.getSubNode( doc, XML_TAG );\n\n        loadXML( jobnode, fname, rep, metaStore, false, prompter );\n      } else {\n        throw new KettleXMLException(\n            BaseMessages.getString( PKG, \"JobMeta.Exception.ErrorReadingFromXMLFile\" ) + fname );\n      }\n    } catch ( Exception e ) {\n      throw new KettleXMLException(\n          BaseMessages.getString( PKG, \"JobMeta.Exception.UnableToLoadJobFromXMLFile\" ) + fname + \"]\", e );\n    }\n  }\n\n  /**\n   * Instantiates a new job meta.\n   *\n   * @param inputStream the input stream\n   * @param rep         the rep\n   * @param prompter    the prompter\n   * @throws KettleXMLException the kettle xml exception\n   */\n  public JobMeta( InputStream inputStream, Repository rep, OverwritePrompter prompter ) throws KettleXMLException {\n    this();","sourceCodeStart":867,"sourceCodeEnd":903,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/engine/src/main/java/org/pentaho/di/job/JobMeta.java#L867-L903","documentation":"JobMeta.loadXML from file: after parsing the document, if the <job> root node (XML_TAG) is absent, doc is non-null but jobnode is effectively null/unusable and this message (plus the file name) is thrown as a KettleXMLException. It means the file exists and parses as XML but is not a Pentaho job document.","triggerScenarios":"Calling JobMeta load-from-file with a file that parses to a DOM whose root is not <job> — e.g. passing a .ktr transformation, an export archive member, a configuration file, or a truncated .kjb missing its root element.","commonSituations":"Wrong file passed to the loader (transformation vs job); file extension renamed but content changed; partially downloaded/truncated .kjb; XML with wrong namespace or an extra wrapper root added by export tools.","solutions":["Verify the file's root element is <job>; if it is <transformation> you are loading a .ktr with the wrong loader.","Re-export or restore the .kjb from backup/version control if it is truncated.","Open the file in a text editor and confirm it starts with <?xml ...?><job> and is complete to </job>.","Load via Spoon to see a friendlier diagnostic, then re-save.","Check you are not passing an archive (zip) path instead of the extracted job XML."],"exampleFix":"// before: loading a transformation as a job\nJobMeta jobMeta = new JobMeta();\njobMeta.loadXML(\"etl.ktr\", null, repo, metaStore, null); // not a <job> doc\n// after\nif (isTransformationFile(\"etl.ktr\")) {\n  TransMeta transMeta = new TransMeta(\"etl.ktr\");\n} else {\n  JobMeta jobMeta = new JobMeta(\"etl.kjb\", repo, metaStore, null);\n}","handlingStrategy":"validation","validationCode":"Document doc = XMLHandler.loadXMLFile(new File(fileName));\nif (doc == null || XMLHandler.getSubNode(doc, \"job\") == null) {\n  throw new IllegalArgumentException(fileName + \" is not a job XML document (missing <job> root)\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  jobMeta.loadXML(fname, rep, metaStore, prompter);\n} catch (KettleXMLException e) {\n  if (e.getMessage().contains(\"ErrorReadingFromXMLFile\") || e.getMessage().contains(fname)) {\n    throw new IllegalArgumentException(\"Not a valid .kjb file: \" + fname, e);\n  }\n  throw e;\n}","preventionTips":["Check the root element (<job> vs <transformation>) before choosing the loader.","Verify file completeness (ends with </job>) after downloads or syncs.","Do not rename .ktr to .kjb (or vice versa) expecting the loader to cope.","Open questionable files in Spoon first to confirm they load."],"tags":["xml","file-loading","job-meta"],"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"}