{"record":{"id":"ed0445381d4d77b7","repo":"apache/seatunnel","slug":"failed-connecting-to-the-configured-jdbc-url-via-j-ed0445","errorCode":null,"errorMessage":"Failed connecting to the configured JDBC URL via JDBC.","messagePattern":"Failed connecting to the configured JDBC URL via JDBC\\.","errorType":"exception","errorClass":"CatalogException","httpStatus":null,"severity":"critical","filePath":"seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/duckdb/DuckDBCatalog.java","lineNumber":127,"sourceCode":"                        try {\n                            Connection connection = driver.connect(url, info);\n                            connectionMap.put(url, connection);\n                            return connection;\n                        } catch (Exception e) {\n                            log.info(\"try connector failed\", e);\n                        }\n                    }\n                }\n            } catch (Exception e) {\n                log.info(\"find driver error, back to DriverManager.getConnection\", e);\n            }\n        }\n        try {\n            Connection connection = DriverManager.getConnection(url, info);\n            connectionMap.put(url, connection);\n            return connection;\n        } catch (SQLException e) {\n            throw new CatalogException(\"Failed connecting to the configured JDBC URL via JDBC.\", e);\n        }\n    }\n\n    @Override\n    public List<CatalogTable> getTables(ReadonlyConfig config) throws CatalogException {\n        // Get the list of specified tables\n        List<String> tableNames = config.get(ConnectorCommonOptions.TABLE_NAMES);\n        if (tableNames != null && !tableNames.isEmpty()) {\n            Iterator<TablePath> tablePaths =\n                    tableNames.stream().map(TablePath::of).filter(this::tableExists).iterator();\n            return buildCatalogTablesWithErrorCheck(tablePaths, config);\n        }\n        // Get the list of table pattern\n        String tablePatternStr = config.get(ConnectorCommonOptions.TABLE_PATTERN);\n        if (StringUtils.isBlank(tablePatternStr)) {\n            return Collections.emptyList();\n        }\n        Pattern tablePattern = Pattern.compile(tablePatternStr);","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/duckdb/DuckDBCatalog.java#L109-L145","documentation":"DuckDBCatalog wraps any SQLException thrown by DriverManager.getConnection when opening a JDBC connection to the configured DuckDB URL. The original SQLException is chained as the cause, so the real reason (bad path, driver missing, lock contention) is in e.getCause(). It signals the catalog could not establish the connection it needs for metadata operations.","triggerScenarios":"Calling getConnection (directly or via any catalog metadata operation like listTables/getTable) when DriverManager.getConnection(url, info) throws an SQLException: malformed URL, DuckDB driver not on classpath, database file locked by another process, or invalid connection properties.","commonSituations":"DuckDB driver (duckdb_jdbc) missing from the plugin/lib directory; the DuckDB file is already opened exclusively by another process (DuckDB allows only one writer); wrong jdbc:duckdb: URL syntax; file path not writable.","solutions":["Check the chained cause (e.getCause()) for the underlying SQLException message","Verify the DuckDB JDBC driver jar is present in the connector classpath (or run install-plugin.sh)","Ensure no other process holds an exclusive lock on the DuckDB database file; close other clients","Validate the URL matches jdbc:duckdb:<path> format (see DuckDBURLParser)","Verify the database file directory exists and is writable"],"exampleFix":"// before\nConnection conn = catalog.getConnection(url, info); // throws CatalogException\n// after\ntry {\n    Connection conn = catalog.getConnection(url, info);\n} catch (CatalogException e) {\n    LOG.error(\"DuckDB connect failed: {}\", e.getCause() != null ? e.getCause().getMessage() : e.getMessage());\n    throw e;\n}","handlingStrategy":"try-catch","validationCode":"String url = config.getUrl();\nif (url == null || !url.startsWith(\"jdbc:duckdb:\")) {\n    throw new IllegalArgumentException(\"Not a DuckDB JDBC URL: \" + url);\n}\nDuckDBURLParser.parse(url); // throws early if malformed","typeGuard":null,"tryCatchPattern":"try {\n    Connection c = catalog.getConnection(url, info);\n} catch (CatalogException e) {\n    Throwable cause = e.getCause();\n    LOG.error(\"DuckDB connection failed: {}\", cause, cause);\n    throw new RuntimeException(\"Check driver classpath and DuckDB file lock\", e);\n}","preventionTips":["Ship the DuckDB JDBC driver jar in the plugin directory (install-plugin.sh)","Ensure only one process opens the DuckDB file at a time (embedded, single-writer)","Validate the URL with DuckDBURLParser.parse before connecting","Keep the DuckDB file path on writable local storage"],"tags":["jdbc","duckdb","connection","catalog"],"backgroundTag":"connection-refused","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}