pentaho/pentaho-kettle · error · KettleDatabaseException
Unable to get database meta-data from the database.
Error message
Unable to get database meta-data from the database.
What it means
Thrown by the private Database.getTableMetaData(schema, table) when connection.getMetaData() returns null, meaning no usable JDBC DatabaseMetaData is available — usually because there is no open connection. It is a precondition guard before querying table descriptions.
Solutions
- Call database.connect() before any API that inspects table metadata
- Verify the connection was not closed earlier in the flow (disconnect in finally too early)
- Check connection.isOpened()/getDatabaseMetaData() != null before invoking metadata-dependent APIs
- Obtain a fresh Database/Connection instance if a previous error invalidated it
Example fix
// before
Database db = new Database(meta);
RowMetaInterface f = db.getTableFields("t"); // metadata null
// after
Database db = new Database(meta);
db.connect();
RowMetaInterface f = db.getTableFields("t"); Defensive patterns
Strategy: type-guard
Validate before calling
if (!database.isOpened() || database.getDatabaseMetaData() == null) {
throw new IllegalStateException("Database metadata unavailable - connect first");
} Type guard
boolean hasDbMeta(Database database) {
return database != null && database.isOpened() && database.getDatabaseMetaData() != null;
} Try / catch
if (!hasDbMeta(database)) {
database.connect();
}
try {
RowMetaInterface fields = database.getTableFields(table);
} catch (KettleDatabaseException e) {
logError("getTableMetaData failed - check connection state", e);
throw e;
} Prevention
- Always call connect() before metadata-dependent APIs
- Do not disconnect until all table-field/DDL operations are done
- Re-create the Database instance after fatal SQLExceptions
- Assert connection state in wrapper utilities
When it happens
Trigger: Calling Database.getTableMetaData indirectly (e.g. getTableFields/getDDL for a table) while the database connection has not been opened or was closed, so getDatabaseMetaData() == null.
Common situations: Steps calling table-field lookups on a Database instance whose connect() was never called or whose disconnect() ran earlier; connections invalidated by a previous fatal SQLException.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Database.Exception.EmptyConnectionError
- Database.Exception.UnableToGetMetadata
- Database type not found!
- DatabaseMeta.Error.DatabaseInterfaceNotFound
- DatabaseMeta.Error.UnableRetrieveDbInfo
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/d4e0960eb66d24e0.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/pentaho/di/core/database/Database.java:2251
throw new KettleDatabaseException(
BaseMessages.getString( PKG, "Database.Error.UnableToCheckExistingTable", tablename, databaseMeta.getName() ),
e );
}
return isTableExist;
}
/**
* Retrieves the table description matching the schema and table name.
*
* @param schema the schema name pattern
* @param table the table name pattern
* @return table description row set
* @throws KettleDatabaseException if DatabaseMetaData is null or some database error occurs
*/
private ResultSet getTableMetaData( String schema, String table ) throws KettleDatabaseException {
ResultSet tables = null;
if ( getDatabaseMetaData() == null ) {
throw new KettleDatabaseException( BaseMessages.getString( PKG, "Database.Error.UnableToGetDbMeta" ) );
}
try {
tables = databaseMeta.getTables(
getDatabaseMetaData(), schema, table, TABLE_TYPES_TO_GET );
} catch ( SQLException e ) {
throw new KettleDatabaseException( BaseMessages.getString( PKG, "Database.Error.UnableToGetTableNames" ), e );
}
if ( tables == null ) {
throw new KettleDatabaseException( BaseMessages.getString( PKG, "Database.Error.UnableToGetTableNames" ) );
}
return tables;
}
/**
* Retrieves the columns metadata matching the schema and table name.
*
* @param schema the schema name pattern
* @param table the table name patternView on GitHub (pinned to f3058517a1)