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

  1. Check DB/network health — the connection was likely already dead before disconnect
  2. Verify the JDBC driver version; some drivers throw on close of stale connections
  3. Ensure disconnect() is called only once per connection lifecycle; or tolerate/ignore this error during cleanup
  4. 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

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


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)