pentaho/pentaho-kettle · error · KettleXMLException
Unable to load job entry of type 'SFTP' from XML node
Error message
Unable to load job entry of type 'SFTP' from XML node
What it means
JobEntrySFTP.loadXML() wraps any KettleXMLException raised while reading the SFTP job entry's XML attributes (including the optional proxy settings) into a new KettleXMLException with the literal message "Unable to load job entry of type 'SFTP' from XML node". It means the <entry type='SFTP'> element in the .kjb file could not be deserialized; the original parse error is attached as cause.
Solutions
- Inspect getCause() to identify the exact tag that failed to parse and correct it in the .kjb file.
- Reopen and re-save the SFTP job entry in Spoon to regenerate valid XML.
- Compare the entry XML against a working SFTP entry saved by the same Kettle version and fix tag names/nesting.
- Confirm the get-file-sftp plugin version matches the Pentaho version loading the job.
Example fix
<!-- before: misspelled/nested tag --> <proxyPasword>secret</proxyPasword> <!-- after --> <proxyPassword>secret</proxyPassword>
Defensive patterns
Strategy: try-catch
Validate before calling
// sanity-check the SFTP entry XML node before loadXML
if ( !"SFTP".equals( XMLHandler.getTagValue( entrynode, "type" ) ) && entrynode.getAttributes() == null ) {
throw new IllegalArgumentException( "Node is not a valid SFTP job entry" );
} Try / catch
try {
entry.loadXML( entrynode, databases, metaStore );
} catch ( KettleXMLException e ) {
log.error( "SFTP entry XML load failed: " + e.getCause() );
throw new KettleException( "Correct the SFTP entry XML in the .kjb file and reload", e );
} Prevention
- Edit SFTP entries via Spoon instead of editing XML directly.
- Validate .kjb files after scripted generation or migration.
- Keep the get-file-sftp plugin at the same version as the Pentaho server.
- Diff suspect entry XML against a known-good entry saved by the same version.
When it happens
Trigger: Loading a job XML where an SFTP entry element is malformed or contains tags XMLHandler cannot parse — e.g., hand-edited XML, wrong nesting, or an attribute structure from a different plugin version — inside the try block covering getTagValue calls and password decryption.
Common situations: Manually editing .kjb files; generating job XML programmatically with wrong tag names; version migration where the SFTP entry schema changed; truncated/corrupted job files.
Related errors
- ColumnExistsMeta.Exception.UnableToReadStepInfo
- CreditCardValidatorMeta.Exception.UnableToReadStepInfo
- CubeOutputMeta.Exception.UnableToLoadStepInfo
- DelayMeta.Exception.UnableToReadStepInfo
- DynamicSQLRowMeta.Exception.UnableToLoadStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/aa5c63c73f322813.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/get-file-sftp/impl/src/main/java/org/pentaho/di/job/entries/sftp/JobEntrySFTP.java:196
isaddresult = "Y".equalsIgnoreCase( addresult );
}
createtargetfolder = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "createtargetfolder" ) );
copyprevious = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "copyprevious" ) );
usekeyfilename = "Y".equalsIgnoreCase( XMLHandler.getTagValue( entrynode, "usekeyfilename" ) );
keyfilename = XMLHandler.getTagValue( entrynode, "keyfilename" );
keyfilepass = Encr.decryptPasswordOptionallyEncrypted( XMLHandler.getTagValue( entrynode, "keyfilepass" ) );
compression = XMLHandler.getTagValue( entrynode, "compression" );
proxyType = XMLHandler.getTagValue( entrynode, "proxyType" );
proxyHost = XMLHandler.getTagValue( entrynode, "proxyHost" );
proxyPort = XMLHandler.getTagValue( entrynode, "proxyPort" );
proxyUsername = XMLHandler.getTagValue( entrynode, "proxyUsername" );
proxyPassword =
Encr.decryptPasswordOptionallyEncrypted( XMLHandler.getTagValue( entrynode, "proxyPassword" ) );
} catch ( KettleXMLException xe ) {
throw new KettleXMLException( "Unable to load job entry of type 'SFTP' from XML node", xe );
}
}
public void loadRep( Repository rep, IMetaStore metaStore, ObjectId id_jobentry, List<DatabaseMeta> databases,
List<SlaveServer> slaveServers ) throws KettleException {
try {
serverName = rep.getJobEntryAttributeString( id_jobentry, "servername" );
serverPort = rep.getJobEntryAttributeString( id_jobentry, "serverport" );
userName = rep.getJobEntryAttributeString( id_jobentry, "username" );
password =
Encr.decryptPasswordOptionallyEncrypted( rep.getJobEntryAttributeString( id_jobentry, "password" ) );
sftpDirectory = rep.getJobEntryAttributeString( id_jobentry, "sftpdirectory" );
targetDirectory = rep.getJobEntryAttributeString( id_jobentry, "targetdirectory" );
wildcard = rep.getJobEntryAttributeString( id_jobentry, "wildcard" );
remove = rep.getJobEntryAttributeBoolean( id_jobentry, "remove" );
View on GitHub (pinned to f3058517a1)