pentaho/pentaho-kettle · error · KettleXMLException
JobEntryZipFile.UnableLoadJobEntryXML
Error message
JobEntryZipFile.UnableLoadJobEntryXML
What it means
JobEntryZipFile.loadXML() throws this KettleXMLException when the zip file job entry's configuration cannot be parsed from its XML node. Any KettleXMLException raised while reading tags like 'SpecifyFormat', 'date_time_format', 'createMoveToDirectory', 'include_subfolders', or 'stored_source_path_depth' is re-wrapped with this message.
Solutions
- Validate the .kjb XML is well-formed (xmllint or an XML editor)
- Check getCause() on the thrown KettleXMLException for the exact parse error and line
- Re-export/re-save the job from Spoon to regenerate valid XML
- Ensure the file was transferred in binary mode and is complete
Example fix
// before: corrupted node <entry name='Zip file'><SpecifyFormat maybe/></entry> // after: valid node <entry name='Zip file'><SpecifyFormat>N</SpecifyFormat><date_time_format></date_time_format><include_subfolders>N</include_subfolders></entry>
Defensive patterns
Strategy: try-catch
Validate before calling
// validate XML before loadXML
try ( InputStream in = new FileInputStream( jobFile ) ) {
Document doc = XMLHandler.loadXMLFile( in );
if ( doc == null ) throw new KettleXMLException( "Invalid XML: " + jobFile );
} Type guard
boolean isParsableXml( File f ) {
try { return XMLHandler.loadXMLFile( new FileInputStream( f ) ) != null; }
catch ( Exception e ) { return false; }
} Try / catch
try {
jobEntry.loadXML( entrynode, databases, slaveServers, rep, metaStore );
} catch ( KettleXMLException e ) {
logError( "ZipFile entry XML load failed: " + e.getCause(), e );
throw; // or restore defaults
} Prevention
- Transfer job files in binary mode only
- Validate .kjb XML after any external generation or templating
- Keep generating and consuming PDI versions in sync
When it happens
Trigger: Calling loadXML on a JobEntryZipFile node that is malformed, truncated, or whose child tags cause XMLHandler to throw (non-XML content, missing entrynode, encoding problems).
Common situations: Corrupt or hand-edited .kjb files; files exported from a newer PDI version; transfer corruption (FTP ASCII mode, incomplete downloads); XML encoding mismatch.
Related errors
- Unable to load base info for job entry
- Unable to load file exists job entry from XML node
- Unable to load job entry from XML node
- Unable to load job entry from XML node
- Unable to load job entry of type 'Msgbox Info' from XML node
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/2c4bc00cd69808d8.
Report an issue: GitHub.
Appendix: source
Thrown at engine/src/main/java/org/pentaho/di/job/entries/zipfile/JobEntryZipFile.java:190
compressionRate = Const.toInt( XMLHandler.getTagValue( entrynode, "compressionrate" ), -1 );
ifZipFileExists = Const.toInt( XMLHandler.getTagValue( entrynode, "ifzipfileexists" ), -1 );
afterZip = Const.toInt( XMLHandler.getTagValue( entrynode, "afterzip" ), -1 );
wildCard = XMLHandler.getTagValue( entrynode, "wildcard" );
excludeWildCard = XMLHandler.getTagValue( entrynode, "wildcardexclude" );
sourceDirectory = XMLHandler.getTagValue( entrynode, "sourcedirectory" );
movetoDirectory = XMLHandler.getTagValue( entrynode, "movetodirectory" );
addFileToResult = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "addfiletoresult" ) );
isFromPrevious = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "isfromprevious" ) );
createParentFolder = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "createparentfolder" ) );
addDate = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "adddate" ) );
addTime = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "addtime" ) );
specifyFormat = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "SpecifyFormat" ) );
dateTimeFormat = XMLHandler.getTagValue( entrynode, "date_time_format" );
createMoveToDirectory = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "createMoveToDirectory" ) );
includingSubFolders = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "include_subfolders" ) );
storedSourcePathDepth = XMLHandler.getTagValue( entrynode, "stored_source_path_depth" );
} catch ( KettleXMLException xe ) {
throw new KettleXMLException( BaseMessages.getString( PKG, "JobEntryZipFile.UnableLoadJobEntryXML" ), xe );
}
}
public void loadRep( Repository rep, IMetaStore metaStore, ObjectId id_jobentry, List<DatabaseMeta> databases,
List<SlaveServer> slaveServers ) throws KettleException {
try {
zipFilename = rep.getJobEntryAttributeString( id_jobentry, "zipfilename" );
compressionRate = (int) rep.getJobEntryAttributeInteger( id_jobentry, "compressionrate" );
ifZipFileExists = (int) rep.getJobEntryAttributeInteger( id_jobentry, "ifzipfileexists" );
afterZip = (int) rep.getJobEntryAttributeInteger( id_jobentry, "afterzip" );
wildCard = rep.getJobEntryAttributeString( id_jobentry, "wildcard" );
excludeWildCard = rep.getJobEntryAttributeString( id_jobentry, "wildcardexclude" );
sourceDirectory = rep.getJobEntryAttributeString( id_jobentry, "sourcedirectory" );
movetoDirectory = rep.getJobEntryAttributeString( id_jobentry, "movetodirectory" );
addFileToResult = rep.getJobEntryAttributeBoolean( id_jobentry, "addfiletoresult" );
isFromPrevious = rep.getJobEntryAttributeBoolean( id_jobentry, "isfromprevious" );
createParentFolder = rep.getJobEntryAttributeBoolean( id_jobentry, "createparentfolder" );
addDate = rep.getJobEntryAttributeBoolean( id_jobentry, "adddate" );View on GitHub (pinned to f3058517a1)