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
- Inspect the chained cause for the driver error (connection reset, deadlock, timeout) and address the root DB/network issue
- Verify network stability and DB-side timeout settings for long transformations using unique connections
- Review step error handling: fix the original step errors that triggered the rollback path
- 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
- Fix the step errors first — errors trigger the rollback path in the first place
- Configure TCP keepalives and adequate timeouts so connections survive long transformations
- Check DB-side deadlock detection and lock wait settings
- Manually verify target table state after this error: the rollback may or may not have been applied
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
- Database.Exception.UnableToRollbackToSavepoint
- Error performing rollback on connection
- JobMeta.Exception.UnableToSaveJobInRepositoryRollbackPerform…
- Unable to create element with name
- Database.Exception.UnableToDisableAutoCommit
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)