pentaho/pentaho-kettle · error · KettleException

Unable to save job entry of type 'ftp' to the repository…

Error message

Unable to save job entry of type 'ftp' to the repository for id_job=

What it means

JobEntryFTP.saveRep() persists all FTP job-entry attributes to the Kettle repository. When any saveJobEntryAttribute call throws a KettleDatabaseException, it is wrapped in this KettleException naming the entry type and id_job. The original database exception is attached as the cause.

Solutions

  1. Check the repository database is reachable and the connection is valid before saving
  2. Inspect the cause (KettleDatabaseException) for the underlying SQL error and fix the schema/permissions
  3. Reconnect to the repository (re-login) and retry the save
  4. Verify the repository user has INSERT/UPDATE rights on the job attribute tables

Example fix

// before
jobEntry.saveRep(rep, metaStore, id_job);
// after
try {
  jobEntry.saveRep(rep, metaStore, id_job);
} catch (KettleException e) {
  logError("Repository save failed: " + e.getCause(), e);
  rep.disconnect();
  rep.connect(login, password);
  jobEntry.saveRep(rep, metaStore, id_job);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (rep == null || !rep.isConnected()) { throw new IllegalStateException("Repository not connected before save"); }

Try / catch

try { entry.saveRep(rep, metaStore, id_job); } catch (KettleException e) { log.error("FTP entry save failed", e.getCause()); /* reconnect & retry */ }

Prevention

When it happens

Trigger: Calling saveRep on a JobEntryFTP whose repository connection is down, the repository schema lacks the required attribute tables/columns, or a database-level constraint/IO error occurs while writing the FTP entry attributes.

Common situations: Repository database offline or networked DB unreachable during save; stale/corrupt repository connection after a long session; migrating repositories across versions with schema drift; permission problems on the repository user.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/598dd4f104658ab2. Report an issue: GitHub.

Appendix: source

Thrown at plugins/get-file-with-ftp/impl/src/main/java/org/pentaho/di/job/entries/ftp/JobEntryFTP.java:468

      rep.saveJobEntryAttribute( id_job, getObjectId(), "isaddresult", isaddresult );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "createmovefolder", createmovefolder );

      rep.saveJobEntryAttribute( id_job, getObjectId(), "proxy_host", proxyHost );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "proxy_port", proxyPort );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "proxy_username", proxyUsername );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "proxy_password", Encr
        .encryptPasswordIfNotUsingVariables( proxyPassword ) );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "socksproxy_host", socksProxyHost );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "socksproxy_port", socksProxyPort );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "socksproxy_username", socksProxyUsername );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "socksproxy_password", Encr
        .encryptPasswordIfNotUsingVariables( socksProxyPassword ) );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "ifFileExists", SifFileExists );

      rep.saveJobEntryAttribute( id_job, getObjectId(), "nr_limit", nr_limit );
      rep.saveJobEntryAttribute( id_job, getObjectId(), "success_condition", success_condition );
    } catch ( KettleDatabaseException dbe ) {
      throw new KettleException(
        "Unable to save job entry of type 'ftp' to the repository for id_job=" + id_job, dbe );
    }
  }

  public void setLimit( String nr_limitin ) {
    this.nr_limit = nr_limitin;
  }

  public String getLimit() {
    return nr_limit;
  }

  public void setSuccessCondition( String success_condition ) {
    this.success_condition = success_condition;
  }

  public String getSuccessCondition() {
    return success_condition;

View on GitHub (pinned to f3058517a1)