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
- Inspect the <entry> XML node for the wait-for-file entry and fix malformed attributes.
- Recreate the job entry in Spoon to regenerate valid XML.
- Validate the .kjb against a known-good file from the same Pentaho version.
- 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
- Use Y/N exactly for boolean XML attributes in hand-written jobs.
- Avoid transforming .kjb XML with naive regex tools.
- Pin the Kettle version used to author and run jobs.
- Store job files with checksums to detect corruption in transfer.
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
- JobEntryTruncateTables.UnableLoadXML
- JobEntryWaitForSQL.UnableLoadXML
- JobPGPEncryptFiles.Error.Exception.UnableLoadXML
- Unable to load job entry of type 'unzip' from XML node
- AddSequenceMeta.Exception.ErrorLoadingStepInfo
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)