pentaho/pentaho-kettle · error · KettleXMLException

Unable to load job entry of type 'wait for file' from XML…

Error message

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

What it means

JobEntryWaitForFile.loadXML() wraps a KettleXMLException raised while reading the 'wait for file' entry's XML attributes into a KettleXMLException with message "Unable to load job entry of type 'wait for file' from XML node". It signals malformed or unparseable XML for this job entry.

Solutions

  1. Inspect the <entry> XML node for the wait-for-file entry and fix malformed attributes.
  2. Recreate the job entry in Spoon to regenerate valid XML.
  3. Validate the .kjb against a known-good file from the same Pentaho version.
  4. Check the cause chain for the exact XMLHandler error (e.g. null sub-node).

Example fix

// before: malformed boolean attribute
<success_on_timeout>yes please</success_on_timeout>
// after
<success_on_timeout>Y</success_on_timeout>
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate required wait-for-file attributes before loadXML
String timeout = XMLHandler.getTagValue(entrynode, "maximum_timeout");
String cycle = XMLHandler.getTagValue(entrynode, "check_cycle_time");
if ( timeout == null || cycle == null )
  throw new KettleXMLException("wait-for-file entry missing timeout attributes");

Type guard

boolean isValidWaitForFileNode(Node entrynode) {
  return entrynode != null
    && XMLHandler.getTagValue(entrynode, "maximum_timeout") != null;
}

Try / catch

try {
  jobEntry.loadXML(entrynode, databases, slaveServers, rep, metaStore);
} catch ( KettleXMLException e ) {
  logError("Bad wait-for-file XML: " + e.getCause().getMessage(), e);
  // skip the entry or load defaults
}

Prevention

When it happens

Trigger: Calling loadXML(...) with an entrynode whose attributes ('maximum_timeout', 'check_cycle_time', 'success_on_timeout', 'file_size_check', 'add_filename_result') are missing or invalid, causing XMLHandler to throw.

Common situations: Hand-edited .kjb files; XML generated by a different Kettle version with renamed attributes; truncated or corrupted file transfers.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/job/entries/waitforfile/JobEntryWaitForFile.java:115

    retval.append( "      " ).append( XMLHandler.addTagValue( "add_filename_result", addFilenameToResult ) );
    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" );
      maximumTimeout = XMLHandler.getTagValue( entrynode, "maximum_timeout" );
      checkCycleTime = XMLHandler.getTagValue( entrynode, "check_cycle_time" );
      successOnTimeout = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "success_on_timeout" ) );
      fileSizeCheck = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "file_size_check" ) );
      addFilenameToResult = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "add_filename_result" ) );
    } catch ( KettleXMLException xe ) {
      throw new KettleXMLException( "Unable to load job entry of type 'wait for 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" );
      maximumTimeout = rep.getJobEntryAttributeString( id_jobentry, "maximum_timeout" );
      checkCycleTime = rep.getJobEntryAttributeString( id_jobentry, "check_cycle_time" );
      successOnTimeout = rep.getJobEntryAttributeBoolean( id_jobentry, "success_on_timeout" );
      fileSizeCheck = rep.getJobEntryAttributeBoolean( id_jobentry, "file_size_check" );
      addFilenameToResult = rep.getJobEntryAttributeBoolean( id_jobentry, "add_filename_result" );
    } catch ( KettleException dbe ) {
      throw new KettleException(
        "Unable to load job entry of type 'wait for file' from the repository for id_jobentry=" + id_jobentry,
        dbe );
    }
  }

View on GitHub (pinned to f3058517a1)