pentaho/pentaho-kettle · error · KettleXMLException

Unable to load job entry of type 'create file' from XML node

Error message

Unable to load job entry of type 'create file' from XML node

What it means

JobEntryCreateFile.loadXML throws this KettleXMLException with a hard-coded message when the XML node for the 'create file' job entry cannot be parsed. The original KettleXMLException is chained as the cause so the real parse failure remains accessible.

Solutions

  1. Validate the entry XML is well-formed and contains <filename>, <fail_if_file_exists>, <add_filename_result> tags.
  2. Check getCause() on the thrown KettleXMLException for the exact parse error.
  3. Recreate the entry in Spoon and re-save the job file.
  4. Regenerate the job file from source control rather than manual edits.

Example fix

// before (malformed)
<filename>/tmp/x.txt<filename>
// after
<filename>/tmp/x.txt</filename>
Defensive patterns

Strategy: try-catch

Validate before calling

Node fn = XMLHandler.getSubNode(entrynode, "filename");
if (fn == null) throw new IllegalArgumentException("create file entry missing <filename> tag");

Try / catch

try {
  jobEntry.loadXML(entrynode, databases, slaveServers);
} catch (KettleXMLException e) {
  logError("Bad 'create file' entry XML: " + e.getCause(), e);
  // skip or rebuild this entry instead of failing the whole job load
}

Prevention

When it happens

Trigger: Calling loadXML on a 'create file' entry node whose 'filename', 'fail_if_file_exists' or 'add_filename_result' tags cause XMLHandler to fail — malformed XML, missing entrynode attributes, or non-element nodes.

Common situations: Hand-edited .kjb files; truncation during file transfer; jobs generated by scripts emitting invalid XML; opening jobs from incompatible Pentaho versions.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/job/entries/createfile/JobEntryCreateFile.java:102

    retval.append( "      " ).append( XMLHandler.addTagValue( "filename", filename ) );
    retval.append( "      " ).append( XMLHandler.addTagValue( "fail_if_file_exists", failIfFileExists ) );
    retval.append( "      " ).append( XMLHandler.addTagValue( "add_filename_result", addfilenameresult ) );
    if ( parentJobMeta != null ) {
      parentJobMeta.getNamedClusterEmbedManager().registerUrl( filename );
    }
    return retval.toString();
  }

  public void loadXML( Node entrynode, List<DatabaseMeta> databases, List<SlaveServer> slaveServers,
    Repository rep, IMetaStore metaStore ) throws KettleXMLException {
    try {
      super.loadXML( entrynode, databases, slaveServers );
      filename = XMLHandler.getTagValue( entrynode, "filename" );
      failIfFileExists = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "fail_if_file_exists" ) );
      addfilenameresult = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "add_filename_result" ) );

    } catch ( KettleXMLException xe ) {
      throw new KettleXMLException( "Unable to load job entry of type 'create file' from XML node", xe );
    }
  }

  public void loadRep( Repository rep, IMetaStore metaStore, ObjectId id_jobentry, List<DatabaseMeta> databases,
    List<SlaveServer> slaveServers ) throws KettleException {
    try {
      filename = rep.getJobEntryAttributeString( id_jobentry, "filename" );
      failIfFileExists = rep.getJobEntryAttributeBoolean( id_jobentry, "fail_if_file_exists" );
      addfilenameresult = rep.getJobEntryAttributeBoolean( id_jobentry, "add_filename_result" );

    } catch ( KettleException dbe ) {
      throw new KettleException(
        "Unable to load job entry of type 'create file' from the repository for id_jobentry=" + id_jobentry, dbe );
    }
  }

  public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_job ) throws KettleException {
    try {

View on GitHub (pinned to f3058517a1)