pentaho/pentaho-kettle · error · KettleXMLException

JobMeta.Exception.UnableToLoadJobFromXMLFile

Error message

JobMeta.Exception.UnableToLoadJobFromXMLFile

What it means

JobMeta throws this KettleXMLException when loading a job from an XML file fails for any reason: the file cannot be read/parsed, the root job node is missing, or an exception occurs while populating the metadata (nested exception 'e' carries the root cause). The message includes the file name in brackets to identify which job file failed.

Solutions

  1. Open the .kjb file and validate it as well-formed XML (xmllint or an XML editor); fix any malformed tags
  2. Verify the file is a job export whose root node is <job>, not a transformation or unrelated XML
  3. Check file read permissions and that the file is not empty or truncated
  4. Inspect the chained cause exception ('Caused by') for the true root cause and fix that first
  5. If the file came from a different PDI version, re-export it from the original tool or upgrade the runtime

Example fix

// before
JobMeta jobMeta = new JobMeta(fileName, null, metaStore);
// after
File f = new File(fileName);
if (!f.isFile() || f.length() == 0) { throw new IllegalArgumentException("Missing/empty job file: " + fileName); }
try {
  JobMeta jobMeta = new JobMeta(fileName, null, metaStore);
} catch (KettleXMLException e) {
  log.error("Cannot load job " + fileName, e); // inspect getCause()
}
Defensive patterns

Strategy: try-catch

Validate before calling

java.io.File f = new java.io.File(fname);
if (!f.isFile() || f.length() == 0) throw new IllegalArgumentException("Job file missing or empty: " + fname);
javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(f); // well-formedness pre-check

Try / catch

try {
  JobMeta jobMeta = new JobMeta(fname, rep, metaStore);
} catch (KettleXMLException e) {
  Throwable cause = e.getCause();
  log.error("Failed to load job " + fname + ": " + (cause != null ? cause.getMessage() : e.getMessage()), e);
}

Prevention

When it happens

Trigger: Calling JobMeta constructors or loadXML(String fname) with an unreadable, malformed, or non-job XML file; the inner loadXML call throws and the catch block wraps it with the 'JobMeta.Exception.UnableToLoadJobFromXMLFile' message plus the file name.

Common situations: Opening a .kjb file that was truncated or hand-edited into invalid XML; pointing at an XML file that is actually a transformation (.ktr) or export fragment; wrong file encoding or BOM; file locked or unreadable due to permissions; loading a job saved by a newer Pentaho version with unknown elements.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/19a08808a435f88d. Report an issue: GitHub.

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/job/JobMeta.java:889

  public JobMeta( Bowl bowl, VariableSpace parentSpace, String fname, Repository rep, IMetaStore metaStore,
      OverwritePrompter prompter ) throws KettleXMLException {
    this.initializeVariablesFrom( parentSpace );
    this.metaStore = metaStore;
    setBowl( bowl );
    try {
      // OK, try to load using the VFS stuff...
      Document doc = XMLHandler.loadXMLFile( KettleVFS.getInstance( bowl ).getFileObject( fname, this ) );
      if ( doc != null ) {
        // The jobnode
        Node jobnode = XMLHandler.getSubNode( doc, XML_TAG );

        loadXML( jobnode, fname, rep, metaStore, false, prompter );
      } else {
        throw new KettleXMLException(
            BaseMessages.getString( PKG, "JobMeta.Exception.ErrorReadingFromXMLFile" ) + fname );
      }
    } catch ( Exception e ) {
      throw new KettleXMLException(
          BaseMessages.getString( PKG, "JobMeta.Exception.UnableToLoadJobFromXMLFile" ) + fname + "]", e );
    }
  }

  /**
   * Instantiates a new job meta.
   *
   * @param inputStream the input stream
   * @param rep         the rep
   * @param prompter    the prompter
   * @throws KettleXMLException the kettle xml exception
   */
  public JobMeta( InputStream inputStream, Repository rep, OverwritePrompter prompter ) throws KettleXMLException {
    this();
    Document doc = XMLHandler.loadXMLFile( inputStream, null, false, false );
    loadXML( XMLHandler.getSubNode( doc, JobMeta.XML_TAG ), rep, prompter );
  }

View on GitHub (pinned to f3058517a1)