pentaho/pentaho-kettle · error · KettleDatabaseException

Trans.Exception.ErrorRollingBackUniqueConnection

Error message

Trans.Exception.ErrorRollingBackUniqueConnection

What it means

At the end of a unique-connection transformation, each database's transactions are rolled back when a step reported errors; this error is thrown if the rollback itself fails. Trans wraps the failed database.rollback(true) into a KettleDatabaseException naming the connection.

Solutions

  1. Inspect the chained cause for the driver error (connection reset, deadlock, timeout) and address the root DB/network issue
  2. Verify network stability and DB-side timeout settings for long transformations using unique connections
  3. Review step error handling: fix the original step errors that triggered the rollback path
  4. Re-run the transformation; if the connection was already dead the data is effectively rolled back server-side

Example fix

// before: connection dead, rollback throws
DB host firewall kills idle connection after 60s
// after: enable keepalive / adjust unique-connection usage
Database > Options: socketTimeout=0, tcpKeepAlive=true
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check connectivity of every unique connection before run
for (DatabaseMeta dbMeta : transMeta.getUsedDatabaseConnections()) {
  if (!dbMeta.testConnectionSuccess()) throw new IllegalStateException("DB unreachable: " + dbMeta.getName());
}

Try / catch

try {
  trans.waitUntilFinished();
} catch (KettleDatabaseException e) {
  if (e.getMessage().contains("ErrorRollingBackUniqueConnection")) {
    // connection likely dead; verify DB-side state manually, transaction probably already lost
    reconcileTargets(e.getMessage());
  } else { throw e; }
}

Prevention

When it happens

Trigger: Running a transformation with 'Unique connections' enabled, at least one step had nrErrors>0, and database.rollback(true) throws (connection already broken/dead-locked/driver error).

Common situations: Connection dropped mid-transformation so rollback cannot be sent, DB deadlock or timeout during rollback, driver-level network failure in long-running transformations.

Related errors


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

Appendix: source

Thrown at engine/src/main/java/org/pentaho/di/trans/Trans.java:3021

    // First we get all the database connections ...
    //
    DatabaseConnectionMap map = DatabaseConnectionMap.getInstance();
    synchronized ( map ) {
      List<Database> databaseList = new ArrayList<>( map.getMap().values() );
      for ( Database database : databaseList ) {
        if ( database.getConnectionGroup().equals( getTransactionId() ) ) {
          try {
            // This database connection belongs to this transformation.
            // Let's roll it back if there is an error...
            //
            if ( result.getNrErrors() > 0 ) {
              try {
                database.rollback( true );
                log.logBasic( BaseMessages.getString( PKG, "Trans.Exception.TransactionsRolledBackOnConnection",
                  database.toString() ) );
              } catch ( Exception e ) {
                throw new KettleDatabaseException( BaseMessages.getString( PKG,
                  "Trans.Exception.ErrorRollingBackUniqueConnection", database.toString() ), e );
              }
            } else {
              try {
                database.commit( true );
                log.logBasic( BaseMessages.getString( PKG, "Trans.Exception.TransactionsCommittedOnConnection", database
                  .toString() ) );
              } catch ( Exception e ) {
                throw new KettleDatabaseException( BaseMessages.getString( PKG,
                  "Trans.Exception.ErrorCommittingUniqueConnection", database.toString() ), e );
              }
            }
          } catch ( Exception e ) {
            log.logError( BaseMessages.getString( PKG, "Trans.Exception.ErrorHandlingTransformationTransaction",
              database.toString() ), e );
            result.setNrErrors( result.getNrErrors() + 1 );
          } finally {
            try {

View on GitHub (pinned to f3058517a1)