{"record":{"id":"15228fd35d8fe9ec","repo":"apache/seatunnel","slug":"couldn-t-obtain-database-name","errorCode":null,"errorMessage":"Couldn't obtain database name","messagePattern":"Couldn't obtain database name","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-sqlserver/src/main/java/io/debezium/connector/sqlserver/SqlServerConnection.java","lineNumber":884,"sourceCode":"    }\n\n    /**\n     * Retrieve the name of the database in the original case as it's defined on the server.\n     *\n     * <p>Although SQL Server supports case-insensitive collations, the connector uses the database\n     * name to build the produced records' source info and, subsequently, the keys of its committed\n     * offset messages. This value must remain the same during the lifetime of the connector\n     * regardless of the case used in the connector configuration.\n     */\n    public String retrieveRealDatabaseName(String databaseName) {\n        try {\n            return prepareQueryAndMap(\n                    GET_DATABASE_NAME,\n                    ps -> ps.setString(1, databaseName),\n                    singleResultMapper(\n                            rs -> rs.getString(1), \"Could not retrieve exactly one database name\"));\n        } catch (SQLException e) {\n            throw new RuntimeException(\"Couldn't obtain database name\", e);\n        }\n    }\n\n    @Override\n    protected boolean isTableUniqueIndexIncluded(String indexName, String columnName) {\n        // SQL Server provides indices also without index name\n        // so we need to ignore them\n        return indexName != null;\n    }\n\n    @Override\n    public <T extends DatabaseSchema<TableId>> Object getColumnValue(\n            ResultSet rs, int columnIndex, Column column, Table table, T schema)\n            throws SQLException {\n        final ResultSetMetaData metaData = rs.getMetaData();\n        final int columnType = metaData.getColumnType(columnIndex);\n\n        if (columnType == Types.TIME) {","sourceCodeStart":866,"sourceCodeEnd":902,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-sqlserver/src/main/java/io/debezium/connector/sqlserver/SqlServerConnection.java#L866-L902","documentation":"Thrown by SqlServerConnection when the query retrieving the current database name (GET_DATABASE_NAME via sys.databases/DB_NAME) fails with a SQLException. It wraps the driver error in a RuntimeException, typically during connector metadata initialization.","triggerScenarios":"Calling the database-name lookup when the SQL Server connection is closed/broken, the login lacks permission to query the database catalog, or the database was dropped/renamed between connecting and the query.","commonSituations":"User without VIEW ANY DATABASE / insufficient catalog permissions; connecting to an availability-group listener during failover; wrong database name in config so DB_NAME() returns null context; network drop mid-query.","solutions":["Verify the configured database name exists and the login can connect to it directly","Grant the login VIEW DEFINITION / catalog read permissions on the database","Check SQL Server error logs and the wrapped SQLException for the exact cause","Reconnect (fresh JdbcConnection) and retry if the connection was dropped","If using an AG listener, retry after failover completes or connect to the primary replica"],"exampleFix":"// before\nString db = connection.getDatabaseName(); // RuntimeException on any SQLException\n// after\ntry {\n    String db = connection.getDatabaseName();\n} catch (RuntimeException e) {\n    LOG.warn(\"db name lookup failed, retrying with fresh connection\", e);\n    JdbcConnection fresh = dialect.openJdbcConnection(config);\n    String db = ((SqlServerConnection) fresh).getDatabaseName();\n}","handlingStrategy":"try-catch","validationCode":"try (Connection c = DriverManager.getConnection(url, user, pass)) {\n    try (ResultSet rs = c.createStatement().executeQuery(\"SELECT DB_NAME()\")) {\n        rs.next(); // throws here if permissions/context are wrong\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    String db = sqlServerConnection.getDatabaseName();\n} catch (RuntimeException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof SQLException) { LOG.error(\"catalog query failed\", cause); }\n    throw e;\n}","preventionTips":["Grant the login catalog read permissions (VIEW DEFINITION) before starting the connector","Use a direct connection to the primary replica, not a flaky listener, for metadata calls","Validate the database name in config matches an existing database","Check SQL Server error logs when metadata queries start failing"],"tags":["sqlserver","jdbc","cdc","database"],"backgroundTag":"database-query-failed","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}