pentaho/pentaho-kettle · warning · KettleDatabaseException
Error disconnecting from database
Error message
Error disconnecting from database '{toString}' What it means
KettleDatabaseException thrown by Database.disconnect() when the underlying Connection.close() call throws a SQLException. The dynamic class loader is still released in the finally block, but the caller is told the JDBC-level disconnect failed. Usually indicates the connection was already in a broken state or a driver-level problem during close.
Solutions
- Check DB/network health — the connection was likely already dead before disconnect
- Verify the JDBC driver version; some drivers throw on close of stale connections
- Ensure disconnect() is called only once per connection lifecycle; or tolerate/ignore this error during cleanup
- Wrap disconnect in try-catch since it typically runs in cleanup paths and the resource is released anyway
Example fix
// before
database.disconnect();
// after
try {
database.disconnect();
} catch (KettleDatabaseException e) {
log.warn("Disconnect failed (connection likely already closed): " + e.getMessage());
} Defensive patterns
Strategy: try-catch
Validate before calling
Connection c = database.getConnection();
if ( c == null || c.isClosed() ) {
log.warn( "Connection already closed; disconnect unnecessary" );
} Type guard
boolean isDisconnectSafe( Database db ) throws SQLException {
Connection c = db.getConnection();
return c != null && !c.isClosed();
} Try / catch
try {
database.disconnect();
} catch ( KettleDatabaseException e ) {
log.warn( "Disconnect failed; connection likely already closed: " + e.getMessage() );
} Prevention
- Call disconnect() exactly once per Database instance
- Keep-Alive / validate connections on long-running jobs to avoid stale handles
- Use try-finally so disconnect always runs, but tolerate its failure
- Update JDBC drivers with known close() bugs
When it happens
Trigger: Calling Database.disconnect() while the JDBC Connection.close() throws SQLException — e.g. connection already terminated by the server, network dropped mid-close, or driver bug in close.
Common situations: Long-running transformations whose connection was killed by the DB (wait_timeout), network outage during shutdown, closing twice after a broken socket.
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.ErrorClosingCallableStatement
- Error closing connection while searching primary keys in…
- Error closing prepared statement
- An error occurred executing SQL:
- An error occurred executing SQL:
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/dbb749ac18d14bcd.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/database/Database.java:1005
/**
* Only for unique connections usage, typically you use disconnect() to disconnect() from the database.
*
* @throws KettleDatabaseException in case there is an error during connection close.
*/
public synchronized void closeConnectionOnly() throws KettleDatabaseException {
try {
if ( connection != null ) {
connection.close();
if ( !databaseMeta.isUsingConnectionPool() ) {
connection = null;
}
}
if ( log.isDetailed() ) {
log.logDetailed( "Connection to database closed!" );
}
} catch ( SQLException e ) {
throw new KettleDatabaseException( "Error disconnecting from database '" + toString() + "'", e );
} finally {
closeDynamicClassLoader();
}
}
/**
* Cancel the open/running queries on the database connection
*
* @throws KettleDatabaseException
*/
public void cancelQuery() throws KettleDatabaseException {
// Canceling statements only if we're not streaming results on MySQL with
// the v3 driver
//
if ( databaseMeta.isMySQLVariant()
&& databaseMeta.isStreamingResults() && getDatabaseMetaData().getDriverMajorVersion() == 3 ) {
return;
}View on GitHub (pinned to f3058517a1)