pentaho/pentaho-kettle · error · KettleDatabaseException
Error performing rollback on connection
Error message
Error performing rollback on connection
What it means
KettleDatabaseException thrown by Database.rollback() when connection.rollback() throws a SQLException. The transaction could not be rolled back — often because the connection itself is already dead, in which case the server rolls back implicitly. Callers should treat the connection as unusable afterwards.
Solutions
- Assume the connection is dead: close it and reconnect; the server will have rolled back the open transaction implicitly
- Check the wrapped SQLException for 'connection closed'-type messages to confirm the connection was already lost
- Avoid rollback loops — guard cleanup code so a failed rollback does not mask the original error
- Verify the connection is not in autocommit mode where rollback is a no-op or unsupported
Example fix
// before
try { database.commit(); } finally { database.rollback(); }
// after
try {
database.commit();
} catch ( Exception e ) {
try {
database.rollback();
} catch ( KettleDatabaseException re ) {
log.warn("Rollback failed, connection likely dead; reconnecting");
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
Connection c = database.getConnection();
if ( c == null || c.isClosed() ) {
return; // server already rolled back implicitly
} Type guard
boolean canRollback( Database db ) throws SQLException {
Connection c = db.getConnection();
return c != null && !c.isClosed();
} Try / catch
try {
database.rollback();
} catch ( KettleDatabaseException e ) {
log.warn( "Rollback failed; reconnecting so server-side rollback applies" );
database.disconnect();
} Prevention
- Do not let rollback failures mask the original exception
- Reconnect after a failed rollback — dead connections imply implicit server rollback
- Keep transactions short and validate connection health before rollback
When it happens
Trigger: Calling Database.rollback() when connection.rollback() throws SQLException — connection terminated by DB/network, rollback attempted in a distributed (XA) context incorrectly, or statement/transaction already completed by the driver.
Common situations: Error-handling paths that roll back after a network failure (rollback then fails too), DB killed the session (wait_timeout), rollback on an autocommit connection.
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
- Database.Exception.UnableToRollbackToSavepoint
- Database.Exception.UnableToDisableAutoCommit
- Database.Exception.UnableToEnableAutoCommit
- Database.Exception.UnableToReleaseSavepoint
- Database.Exception.UnableToSetSavepoint
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/f7964c949be4bce6.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/database/Database.java:1202
public void rollback( boolean force ) throws KettleDatabaseException {
try {
if ( !Utils.isEmpty( connectionGroup ) && !force ) {
return; // Will be handled by Trans --> endProcessing()
}
if ( getDatabaseMetaData().supportsTransactions() ) {
if ( connection != null ) {
if ( log.isDebug() ) {
log.logDebug( "Rollback on database connection [" + toString() + "]" );
}
connection.rollback();
}
} else {
if ( log.isDetailed() ) {
log.logDetailed( "No rollback possible on database connection [" + toString() + "]" );
}
}
} catch ( SQLException e ) {
throw new KettleDatabaseException( "Error performing rollback on connection", e );
}
}
/**
* Prepare inserting values into a table, using the fields & values in a Row
*
* @param rowMeta The row metadata to determine which values need to be inserted
* @param tableName The name of the table in which we want to insert rows
* @throws KettleDatabaseException if something went wrong.
*/
public void prepareInsert( RowMetaInterface rowMeta, String tableName ) throws KettleDatabaseException {
prepareInsert( rowMeta, null, tableName );
}
/**
* Prepare inserting values into a table, using the fields & values in a Row
*
* @param rowMeta The metadata row to determine which values need to be insertedView on GitHub (pinned to f3058517a1)