pentaho/pentaho-kettle · error · KettleException
JobFTPSPUT.UnableToLoadFromRepo
JobFTPSPUT.UnableToLoadFromRepo
Error message
JobFTPSPUT.UnableToLoadFromRepo
What it means
JobEntryFTPSPUT.loadRep() throws this KettleException when reading the job entry's attributes from the Kettle repository fails. Any KettleException from rep.getJobEntryAttributeString(...) or from FTPSConnection.getConnectionTypeByCode (invalid stored connection_type) is rethrown with the JobFTPSPUT.UnableToLoadFromRepo message plus the id_jobentry, with the database exception as cause.
Solutions
- Read the cause (KettleException/KettleDatabaseException) and verify repository connectivity and credentials.
- Check r_jobentry_attribute rows for the given id_jobentry and repair or delete the broken entry, then recreate it in Spoon.
- Confirm the stored connection_type matches a valid FTPSConnection code for the installed plugin version.
- Re-save the job entry with a matching plugin version so attributes are written in the expected format.
Example fix
// before: blindly loading with a stale ObjectId JobEntryFTPSPUT entry = new JobEntryFTPSPUT(); entry.loadRep( rep, metaStore, unknownId, databases, slaveServers ); // after: verify the entry exists first RowMetaAndData row = rep.getJobEntry( id_jobentry ); if ( row == null ) throw new KettleException( "Job entry " + id_jobentry + " missing from repository" ); entry.loadRep( rep, metaStore, id_jobentry, databases, slaveServers );
Defensive patterns
Strategy: try-catch
Validate before calling
// verify the entry exists and repository is reachable before loadRep
if ( !rep.isConnected() || rep.getJobEntry( id_jobentry ) == null ) {
throw new KettleException( "Cannot load FTPSPUT entry " + id_jobentry + ": repository/entry unavailable" );
} Try / catch
try {
entry.loadRep( rep, metaStore, id_jobentry, databases, slaveServers );
} catch ( KettleException e ) {
log.error( "Repo load failed for FTPSPUT entry " + id_jobentry + ": " + e.getCause() );
throw new KettleException( "Check repository connectivity and r_jobentry_attribute rows, then reload", e );
} Prevention
- Test the repository connection before loading jobs.
- Never delete r_jobentry_attribute rows manually; use Spoon to remove entries.
- Run repository upgrade scripts after Pentaho version changes.
- Confirm plugin versions match between save-time and load-time.
When it happens
Trigger: Loading an FTPSput job entry by ObjectId from a repository where the r_jobentry_attribute rows are missing/corrupt, the repository connection fails mid-read, or the stored connection_type string is not a recognized FTPS connection code.
Common situations: Repository schema drift after upgrading Pentaho; rows deleted from r_jobentry_attribute; repository database connectivity problems; entries saved by a newer plugin version with connection types the current code doesn't know.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- AccessInputMeta.Exception.ErrorReadingRepository
- AddSequenceMeta.Exception.UnableToReadStepInfo
- AggregateRowsMeta.Exception.UnexpectedErrorWhileReadingStepInfo
- AnalyticQueryMeta.Exception.UnexpectedErrorInReadingStepInfo…
- AppendMeta.Exception.UnableToSaveStepInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/21e45c3be2c1a1e2.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/ftps/impl/src/main/java/org/pentaho/di/job/entries/ftpsput/JobEntryFTPSPUT.java:192
Encr.decryptPasswordOptionallyEncrypted( rep.getJobEntryAttributeString( id_jobentry, "password" ) );
remoteDirectory = rep.getJobEntryAttributeString( id_jobentry, "remoteDirectory" );
localDirectory = rep.getJobEntryAttributeString( id_jobentry, "localDirectory" );
wildcard = rep.getJobEntryAttributeString( id_jobentry, "wildcard" );
binaryMode = rep.getJobEntryAttributeBoolean( id_jobentry, "binary" );
timeout = rep.getJobEntryAttributeString( id_jobentry, "timeout" );
remove = rep.getJobEntryAttributeBoolean( id_jobentry, "remove" );
onlyPuttingNewFiles = rep.getJobEntryAttributeBoolean( id_jobentry, "only_new" );
activeConnection = rep.getJobEntryAttributeBoolean( id_jobentry, "active" );
proxyHost = rep.getJobEntryAttributeString( id_jobentry, "proxy_host" );
proxyPort = rep.getJobEntryAttributeString( id_jobentry, "proxy_port" );
proxyUsername = rep.getJobEntryAttributeString( id_jobentry, "proxy_username" );
proxyPassword = rep.getJobEntryAttributeString( id_jobentry, "proxy_password" );
connectionType =
FTPSConnection.getConnectionTypeByCode( Const.NVL( rep.getJobEntryAttributeString(
id_jobentry, "connection_type" ), "" ) );
} catch ( KettleException dbe ) {
throw new KettleException( BaseMessages.getString( PKG, "JobFTPSPUT.UnableToLoadFromRepo", String
.valueOf( id_jobentry ) ), dbe );
}
}
public void saveRep( Repository rep, IMetaStore metaStore, ObjectId id_job ) throws KettleException {
try {
rep.saveJobEntryAttribute( id_job, getObjectId(), "servername", serverName );
rep.saveJobEntryAttribute( id_job, getObjectId(), "serverport", serverPort );
rep.saveJobEntryAttribute( id_job, getObjectId(), "username", userName );
rep.saveJobEntryAttribute( id_job, getObjectId(), "password", Encr
.encryptPasswordIfNotUsingVariables( password ) );
rep.saveJobEntryAttribute( id_job, getObjectId(), "remoteDirectory", remoteDirectory );
rep.saveJobEntryAttribute( id_job, getObjectId(), "localDirectory", localDirectory );
rep.saveJobEntryAttribute( id_job, getObjectId(), "wildcard", wildcard );
rep.saveJobEntryAttribute( id_job, getObjectId(), "binary", binaryMode );
rep.saveJobEntryAttribute( id_job, getObjectId(), "timeout", timeout );
rep.saveJobEntryAttribute( id_job, getObjectId(), "remove", remove );
rep.saveJobEntryAttribute( id_job, getObjectId(), "only_new", onlyPuttingNewFiles );View on GitHub (pinned to f3058517a1)