{"record":{"id":"b695aab205a483ef","repo":"apache/iceberg","slug":"cannot-initialize-jdbc-table-maintenance-lock-con","errorCode":null,"errorMessage":"Cannot initialize JDBC table maintenance lock: Connection failed","messagePattern":"Cannot initialize JDBC table maintenance lock: Connection failed","errorType":"exception","errorClass":"UncheckedSQLException","httpStatus":null,"severity":"critical","filePath":"flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/JdbcLockFactory.java","lineNumber":152,"sourceCode":"                    LOCK_TABLE_NAME /* tableNamePattern */,\n                    null /* types */)) {\n              if (rs.next()) {\n                LOG.debug(\"Flink maintenance lock table already exists\");\n                return true;\n              }\n            }\n            LOG.info(\"Creating Flink maintenance lock table {}\", LOCK_TABLE_NAME);\n            try (PreparedStatement ps = conn.prepareStatement(CREATE_LOCK_TABLE_SQL)) {\n              ps.execute();\n            }\n\n            return true;\n          });\n    } catch (SQLTimeoutException e) {\n      throw new UncheckedSQLException(\n          e, \"Cannot initialize JDBC table maintenance lock: Query timed out\");\n    } catch (SQLTransientConnectionException | SQLNonTransientConnectionException e) {\n      throw new UncheckedSQLException(\n          e, \"Cannot initialize JDBC table maintenance lock: Connection failed\");\n    } catch (SQLException e) {\n      throw new UncheckedSQLException(e, \"Cannot initialize JDBC table maintenance lock\");\n    } catch (InterruptedException e) {\n      Thread.currentThread().interrupt();\n      throw new UncheckedInterruptedException(e, \"Interrupted in call to initialize\");\n    }\n  }\n\n  private static class JdbcLock implements TriggerLockFactory.Lock {\n    private final JdbcClientPool pool;\n    private final String lockId;\n    private final Type type;\n\n    private JdbcLock(JdbcClientPool pool, String lockId, Type type) {\n      this.pool = pool;\n      this.lockId = lockId;\n      this.type = type;","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/JdbcLockFactory.java#L134-L170","documentation":"JdbcLockFactory.initializeLockTables catches SQLTransientConnectionException and SQLNonTransientConnectionException separately from generic timeouts and wraps them as UncheckedSQLException with a 'Connection failed' message, signaling the JDBC connection to the lock database could not be established or was dropped.","triggerScenarios":"JdbcLockFactory.open() where the driver reports SQLTransientConnectionException (transient connect failure, e.g. too many connections) or SQLNonTransientConnectionException (bad URL, auth refused, connection dropped).","commonSituations":"Wrong JDBC URL/host/port, DB connection pool exhausted (max_connections reached), firewall or TLS handshake failures, DB restarted mid-initialization.","solutions":["Verify the JDBC URI, host, port, and credentials in the maintenance lock configuration.","Check DB max_connections and current connection count; raise limits or reduce pool size if exhausted.","Test connectivity from the Flink host (e.g. nc/psql) and check firewalls, security groups, TLS settings.","If transient, retry the job after the DB recovers; consider increasing connect timeout in the JDBC URL."],"exampleFix":"// before\n.option(\"uri\", \"jdbc:mysql://db-host:3306/iceberg\")\n\n// after: add connect timeout and correct DB\n.option(\"uri\", \"jdbc:mysql://db-host:3306/iceberg?connectTimeout=10000&socketTimeout=30000\")","handlingStrategy":"retry","validationCode":"// preflight connectivity check\ntry (Connection c = DriverManager.getConnection(uri, user, password)) {\n    if (!c.isValid(5)) throw new IllegalStateException(\"JDBC connection invalid\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    lockFactory.open();\n} catch (UncheckedSQLException e) {\n    Throwable cause = e.getCause();\n    if (cause instanceof SQLTransientConnectionException) {\n        retryWithBackoff(); // transient: retry is appropriate\n    } else {\n        throw e; // non-transient: fix config/credentials first\n    }\n}","preventionTips":["Validate JDBC URI and credentials before deploying","Monitor DB max_connections usage","Add connectTimeout/socketTimeout to the JDBC URL","Test network/firewall paths from the Flink host"],"tags":["jdbc","flink","database","connection","maintenance-lock"],"backgroundTag":"connection-refused","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}