{"record":{"id":"d4e0960eb66d24e0","repo":"pentaho/pentaho-kettle","slug":"unable-to-get-database-meta-data-from-the-database","errorCode":null,"errorMessage":"Unable to get database meta-data from the database.","messagePattern":"Unable to get database meta-data from the database\\.","errorType":"exception","errorClass":"KettleDatabaseException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/database/Database.java","lineNumber":2251,"sourceCode":"      throw new KettleDatabaseException(\n        BaseMessages.getString( PKG, \"Database.Error.UnableToCheckExistingTable\", tablename, databaseMeta.getName() ),\n        e );\n    }\n    return isTableExist;\n  }\n\n  /**\n   * Retrieves the table description matching the schema and table name.\n   *\n   * @param schema the schema name pattern\n   * @param table  the table name pattern\n   * @return table description row set\n   * @throws KettleDatabaseException if DatabaseMetaData is null or some database error occurs\n   */\n  private ResultSet getTableMetaData( String schema, String table ) throws KettleDatabaseException {\n    ResultSet tables = null;\n    if ( getDatabaseMetaData() == null ) {\n      throw new KettleDatabaseException( BaseMessages.getString( PKG, \"Database.Error.UnableToGetDbMeta\" ) );\n    }\n    try {\n      tables = databaseMeta.getTables(\n        getDatabaseMetaData(), schema, table, TABLE_TYPES_TO_GET );\n    } catch ( SQLException e ) {\n      throw new KettleDatabaseException( BaseMessages.getString( PKG, \"Database.Error.UnableToGetTableNames\" ), e );\n    }\n    if ( tables == null ) {\n      throw new KettleDatabaseException( BaseMessages.getString( PKG, \"Database.Error.UnableToGetTableNames\" ) );\n    }\n    return tables;\n  }\n\n  /**\n   * Retrieves the columns metadata matching the schema and table name.\n   *\n   * @param schema the schema name pattern\n   * @param table  the table name pattern","sourceCodeStart":2233,"sourceCodeEnd":2269,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/database/Database.java#L2233-L2269","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nDatabase db = new Database(meta);\nRowMetaInterface f = db.getTableFields(\"t\"); // metadata null\n// after\nDatabase db = new Database(meta);\ndb.connect();\nRowMetaInterface f = db.getTableFields(\"t\");","handlingStrategy":"type-guard","validationCode":"if (!database.isOpened() || database.getDatabaseMetaData() == null) {\n  throw new IllegalStateException(\"Database metadata unavailable - connect first\");\n}","typeGuard":"boolean hasDbMeta(Database database) {\n  return database != null && database.isOpened() && database.getDatabaseMetaData() != null;\n}","tryCatchPattern":"if (!hasDbMeta(database)) {\n  database.connect();\n}\ntry {\n  RowMetaInterface fields = database.getTableFields(table);\n} catch (KettleDatabaseException e) {\n  logError(\"getTableMetaData failed - check connection state\", e);\n  throw e;\n}","preventionTips":["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"],"tags":["database","metadata","connection-state"],"backgroundTag":"internal-invariant-violation","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}