pentaho/pentaho-kettle · error · KettleException

TransMeta.Log.UnableToReadSlaveServersFromRepository

Error message

TransMeta.Log.UnableToReadSlaveServersFromRepository

What it means

Thrown in the readSlaves() portion of KettleDatabaseRepositoryTransDelegate when reading slave servers associated with a transformation fails with a KettleDatabaseException. Slave servers are clustered execution nodes stored in R_SLAVE; failure to load them aborts shared-object loading for the transformation. The low-level database exception is chained for diagnosis.

Solutions

  1. Check the chained cause for the exact database error message
  2. Verify R_SLAVE exists and matches the schema of your Pentaho/Kettle version
  3. Grant the repository user SELECT on R_SLAVE
  4. Test repository connectivity (Connect/Explore in Spoon) before loading transformations

Example fix

// before
TransMeta tm = new TransMeta(rep, "myTrans", rep.getDirectoryTree().findDirectory(dir));
// may wrap KettleDatabaseException

// after
if (!rep.connect().isConnected()) { /* fix connection first */ }
TransMeta tm = new TransMeta(rep, "myTrans", rep.getDirectoryTree().findDirectory(dir));
Defensive patterns

Strategy: try-catch

Validate before calling

// Java: ensure R_SLAVE is queryable before load
Database db = new Database(loggingObject, repository.getDatabaseMeta());
db.connect();
boolean ok = db.checkTableExists("R_SLAVE");
db.disconnect();
if (!ok) throw new IllegalStateException("R_SLAVE missing from repository");

Try / catch

try {
  transMeta = rep.loadTransformation(...);
} catch (KettleException e) {
  log.error("Slave server read failed: " + e.getCause(), e);
  // proceed without clustering or abort, per business need
}

Prevention

When it happens

Trigger: readTransSharedObjects -> readSlaves querying R_SLAVE fails: table absent, connection failure, SQL permission error, or a KettleDatabaseException while mapping rows to SlaveServer objects.

Common situations: Repository upgraded incompletely (R_SLAVE missing), DB account lacking SELECT on R_SLAVE, network interruption to the repository DB, or bad data in slave rows.

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


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/repository/kdr/delegates/KettleDatabaseRepositoryTransDelegate.java:1050

  public void readSlaves( TransMeta transMeta, boolean overWriteShared ) throws KettleException {
    try {
      ObjectId[] dbids = repository.getSlaveIDs( false );
      for ( int i = 0; i < dbids.length; i++ ) {
        SlaveServer slaveServer = repository.loadSlaveServer( dbids[i], null ); // Load last version
        slaveServer.shareVariablesWith( transMeta );
        SlaveServer check = transMeta.findSlaveServer( slaveServer.getName() ); // Check if there already is one in the
                                                                                // transformation
        if ( check == null || overWriteShared ) {
          if ( !Utils.isEmpty( slaveServer.getName() ) ) {
            transMeta.addOrReplaceSlaveServer( slaveServer );
            if ( !overWriteShared ) {
              slaveServer.setChanged( false );
            }
          }
        }
      }
    } catch ( KettleDatabaseException dbe ) {
      throw new KettleException( BaseMessages.getString(
        PKG, "TransMeta.Log.UnableToReadSlaveServersFromRepository" ), dbe );
    }
  }

  public TransDependency loadTransDependency( ObjectId id_dependency, List<DatabaseMeta> databases ) throws KettleException {
    TransDependency transDependency = new TransDependency();

    try {
      transDependency.setObjectId( id_dependency );

      RowMetaAndData r = getTransDependency( id_dependency );

      if ( r != null ) {
        long id_connection = r.getInteger( "ID_DATABASE", 0 );
        transDependency.setDatabase( DatabaseMeta.findDatabase( databases, new LongObjectId( id_connection ) ) );
        transDependency.setTablename( r.getString( "TABLE_NAME", null ) );
        transDependency.setFieldname( r.getString( "FIELD_NAME", null ) );
      }

View on GitHub (pinned to f3058517a1)