{"record":{"id":"a8c69687ac7eb320","repo":"apache/iceberg","slug":"cannot-initialize-jdbc-table-maintenance-lock-a8c696","errorCode":null,"errorMessage":"Cannot initialize JDBC table maintenance lock","messagePattern":"Cannot initialize JDBC table maintenance lock","errorType":"exception","errorClass":"UncheckedSQLException","httpStatus":null,"severity":"error","filePath":"flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/JdbcLockFactory.java","lineNumber":155,"sourceCode":"                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;\n    }\n\n    @Override","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/JdbcLockFactory.java#L137-L173","documentation":"Catch-all handler in JdbcLockFactory.initializeLockTables: any SQLException not classified as a timeout or connection failure during lock-table initialization is wrapped in UncheckedSQLException with this generic message. Inspect the cause for the actual SQL error (e.g. syntax, permissions, table already exists in an incompatible state).","triggerScenarios":"JdbcLockFactory.create/open -> initializeLockTables when executing the lock-table DDL/query throws any other SQLException (permission denied, syntax error, catalog missing, etc.).","commonSituations":"DB user lacking CREATE TABLE privileges, unsupported SQL dialect, schema/database not existing, or a partially created lock table from a failed earlier run.","solutions":["Inspect the wrapped SQLException cause for the root SQL error code and message.","Grant the DB user CREATE/INSERT/SELECT privileges on the target schema.","Create the lock tables manually with the expected schema (id/name columns per JdbcLockFactory) so runtime DDL is a no-op.","Verify the JDBC URL points to the intended database/schema."],"exampleFix":"// before (no privileges)\nGRANT CONNECT ON DATABASE app TO flink_user;\n// after\nGRANT CONNECT, CREATE ON DATABASE app TO flink_user;","handlingStrategy":"validation","validationCode":"// verify privileges and table existence up front\nSELECT has_database_privilege(current_user, 'app', 'CREATE');\nSELECT to_regclass('public.iceberg_lock'); -- null means tables will be created","typeGuard":null,"tryCatchPattern":"try {\n  lockFactory.open();\n} catch (UncheckedSQLException e) {\n  SQLException sql = (SQLException) e.getCause();\n  // log sql.getSQLState() and sql.getErrorCode() to identify the real cause\n  throw e;\n}","preventionTips":["Grant CREATE privileges to the lock-factory DB user","Create lock tables manually via migration scripts","Always log the wrapped cause's SQLState/ErrorCode","Confirm the JDBC URL schema/database exists"],"tags":["jdbc","sql-exception","database","lock"],"backgroundTag":"database-query-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}