pentaho/pentaho-kettle · error · KettleXMLException
Unable to load job entry of type 'SFTPPUT' from XML node
Error message
Unable to load job entry of type 'SFTPPUT' from XML node
What it means
JobEntrySFTPPUT.loadXML catches KettleXMLException while reading the SFTP Put entry's tags from the XML node and rethrows 'Unable to load job entry of type SFTPPUT from XML node' with the original exception chained. It means the entry could not be deserialized from the .kjb XML.
Solutions
- Open the .kjb in an editor and validate the SFTPPUT entry XML block (tags like destinationfolder, createdestinationfolder, successWhenNoFile).
- Check the chained KettleXMLException (xe) for the exact parse error and line.
- Recreate the SFTP Put entry in Spoon and re-save the job.
- Restore the job file from version control or a backup if it was corrupted by editing/merging.
Defensive patterns
Strategy: validation
Validate before calling
Node entryNode = XMLHandler.getSubNode(jobnode, "entry"); if ( entryNode == null || XMLHandler.getTagValue(entryNode, "type") == null ) { throw new IllegalArgumentException("Invalid SFTPPUT entry node"); } Try / catch
try { entry.loadXML(node, databases, slaveServers, rep, metaStore); } catch (KettleXMLException e) { log.error("SFTPPUT XML load failed: " + e.getCause(), e); } Prevention
- Edit job files only via Spoon; avoid manual XML merging.
- Round-trip test .kjb files (load + save) in CI.
- Keep Pentaho versions in sync across environments.
When it happens
Trigger: Calling loadXML when XMLHandler.getTagValue encounters malformed/missing structure in the entrynode — corrupted <entry> block, unexpected null node, or wrong node type passed to this loader.
Common situations: Truncated or hand-edited .kjb files; XML produced by incompatible Pentaho versions; copy-paste corruption; merging job files incorrectly in version control.
Related errors
- ERROR_0001_Cannot_Load_Job_Entry_From_Xml_Node
- ERROR_0001_Cannot_Load_Job_Entry_From_Xml_Node
- ERROR_0001_Cannot_Load_Job_Entry_From_Xml_Node
- ERROR_0001_Unable_To_Load_From_Xml_Node
- JobEntryAbort.UnableToLoadFromXml.Label
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/09d56aa03eeefa2d.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/put-file-sftp/impl/src/main/java/org/pentaho/di/job/entries/sftpput/JobEntrySFTPPUT.java:233
proxyPort = XMLHandler.getTagValue( entrynode, "proxyPort" );
proxyUsername = XMLHandler.getTagValue( entrynode, "proxyUsername" );
proxyPassword =
Encr.decryptPasswordOptionallyEncrypted( XMLHandler.getTagValue( entrynode, "proxyPassword" ) );
createRemoteFolder = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "createRemoteFolder" ) );
boolean remove = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "remove" ) );
setAfterFTPS( getAfterSFTPPutByCode( Const.NVL( XMLHandler.getTagValue( entrynode, "aftersftpput" ), "" ) ) );
if ( remove && getAfterFTPS() == AFTER_FTPSPUT_NOTHING ) {
setAfterFTPS( AFTER_FTPSPUT_DELETE );
}
destinationfolder = XMLHandler.getTagValue( entrynode, "destinationfolder" );
createDestinationFolder =
"Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "createdestinationfolder" ) );
successWhenNoFile = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "successWhenNoFile" ) );
} catch ( KettleXMLException xe ) {
throw new KettleXMLException( "Unable to load job entry of type 'SFTPPUT' from XML node", xe );
}
}
public static int getAfterSFTPPutByCode( String tt ) {
if ( tt == null ) {
return 0;
}
for ( int i = 0; i < afterFTPSCode.length; i++ ) {
if ( afterFTPSCode[i].equalsIgnoreCase( tt ) ) {
return i;
}
}
return 0;
}
public static String getAfterSFTPPutDesc( int i ) {
if ( i < 0 || i >= afterFTPSDesc.length ) {View on GitHub (pinned to f3058517a1)