pentaho/pentaho-kettle · error · KettleDatabaseException
Unable to close resultset
Error message
Unable to close resultset
What it means
Thrown by Database.getOneRow( String sql ) when the java.sql.ResultSet returned by openQuery cannot be closed (rs.close() throws). The row was already fetched, but the driver failed to release the resultset resource, so Kettle aborts with a KettleDatabaseException wrapping the underlying SQLException cause. It almost always reflects a connection or driver-level problem rather than bad SQL.
Solutions
- Check the wrapped cause (KettleDatabaseException.getCause()) to see the real SQLException and fix the underlying connection/driver issue
- Ensure the Database connection is open and healthy before calling getOneRow; reconnect with db.connect() if disconnect() was called or the connection timed out
- Upgrade the JDBC driver for the target database to a current version
- Avoid sharing a single Database instance across threads; use one instance per thread/execution
Example fix
// before
RowMetaAndData r = database.getOneRow( "SELECT COUNT(*) FROM t" ); // may throw on close
// after
RowMetaAndData r = null;
try {
r = database.getOneRow( "SELECT COUNT(*) FROM t" );
} catch ( KettleDatabaseException e ) {
logError( "Failed to fetch/close: " + e.getCause(), e );
database.disconnect();
database.connect();
r = database.getOneRow( "SELECT COUNT(*) FROM t" );
} Defensive patterns
Strategy: try-catch
Validate before calling
if ( database == null || !isConnected( database ) ) {
throw new IllegalStateException( "Database connection is not open; call connect() before getOneRow()" );
} Type guard
boolean isUsable( Database db ) {
return db != null && db.getConnection() != null; // non-null open JDBC connection
} Try / catch
try {
RowMetaAndData row = database.getOneRow( sql );
} catch ( KettleDatabaseException e ) {
Throwable cause = e.getCause();
log.logError( "getOneRow cleanup failed: " + ( cause != null ? cause.getMessage() : e.getMessage() ), e );
database.disconnect();
database.connect();
// retry once or degrade gracefully
} Prevention
- Always verify the connection is open before querying; reconnect after idle periods
- Read e.getCause() — the real SQLException explains whether close or the connection failed
- Use one Database instance per thread to avoid concurrent close races
- Keep JDBC drivers up to date; old drivers often throw on closing exhausted resultsets
When it happens
Trigger: Calling db.getOneRow( sql ) where openQuery succeeded, getRow fetched a row, but ResultSet.close() threw — e.g. the JDBC connection was already closed/broken, the driver threw an SQL exception during close, or the statement/resultset was closed elsewhere concurrently.
Common situations: Connection dropped mid-operation (network timeout, server restart, wait_timeout expiry); calling getOneRow on a Database whose connection was disconnected beforehand; buggy or old JDBC drivers that throw on closing an exhausted resultset; concurrent use of one Database object from multiple threads.
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
- Couldn't close query: resultset or prepared statements
- Error closing
- Unable to close prepared statement pstmt
- Unable to close prepared statement sel_stmt
- : Unable to get Internet Address from resultset at index "…
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/25118ab290095478.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/database/Database.java:3612
execStatement( "DELETE FROM " + databaseMeta.getQuotedSchemaTableCombination( schema, tablename ) );
}
}
/**
* Execute a query and return at most one row from the resultset
*
* @param sql The SQL for the query
* @return one Row with data or null if nothing was found.
*/
public RowMetaAndData getOneRow( String sql ) throws KettleDatabaseException {
ResultSet rs = openQuery( sql );
if ( rs != null ) {
Object[] row = getRow( rs ); // One row only
try {
rs.close();
} catch ( Exception e ) {
throw new KettleDatabaseException( "Unable to close resultset", e );
}
if ( pstmt != null ) {
try {
pstmt.close();
} catch ( Exception e ) {
throw new KettleDatabaseException( "Unable to close prepared statement pstmt", e );
}
pstmt = null;
}
if ( selStmt != null ) {
try {
selStmt.close();
} catch ( Exception e ) {
throw new KettleDatabaseException( "Unable to close prepared statement sel_stmt", e );
}
selStmt = null;
}View on GitHub (pinned to f3058517a1)