apache/iceberg · error · UncheckedSQLException
Failed to check the state of the lock %s
Error message
Failed to check the state of the lock %s
What it means
JdbcLockFactory's JdbcLock.isHeld() queries the JDBC lock table to determine whether this trigger holds the maintenance lock. Any SQLException from the underlying JDBC connection/query is wrapped into UncheckedSQLException with this message. The error means the lock state could not be read, not that the lock is (or is not) held.
Source
Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/JdbcLockFactory.java:230
@Override
public boolean isHeld() {
try {
return pool.run(
conn -> {
try (PreparedStatement sql = conn.prepareStatement(GET_LOCK_SQL)) {
sql.setString(1, type.key);
sql.setString(2, lockId);
try (ResultSet rs = sql.executeQuery()) {
return rs.next();
}
}
});
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new UncheckedInterruptedException(e, "Interrupted during isHeld");
} catch (SQLException e) {
// SQL exception happened when getting lock information
throw new UncheckedSQLException(e, "Failed to check the state of the lock %s", this);
}
}
@SuppressWarnings("checkstyle:NestedTryDepth")
@Override
public void unlock() {
try {
// Possible concurrency issue:
// - `unlock` and `tryLock` happens at the same time when there is an existing lock
//
// Steps:
// 1. `unlock` removes the lock in the database, but there is a temporary connection failure
// 2. `lock` finds that there is no lock, so creates a new lock
// 3. `unlock` retries the lock removal and removes the new lock
//
// To prevent the situation above we fetch the current lockId, and remove the lock
// only with the given id.
String instanceId = instanceId();View on GitHub (pinned to 86d9c8fc54)
Solutions
- Verify the database is reachable and the lock table exists (run the JdbcCatalog table-create SQL against it).
- Test credentials in the JDBC URI by connecting with a plain SQL client.
- Check network/firewall/Security Group rules between the Flink cluster and the DB host.
- Inspect the cause (UncheckedSQLException.getCause()) for the exact SQLState to distinguish connectivity from schema/permission problems.
- If transient, retry triggerLock/table maintenance after the DB recovers; the exception is unchecked so callers must catch UncheckedSQLException.
Example fix
// before
String jdbcUrl = "jdbc:mysql://db-host:3306/iceberg"; // db down -> UncheckedSQLException
TableMaintenance.forTable(table).lockFactory(JdbcLockFactory.builder().setJdbcUrl(jdbcUrl).build());
// after
// pre-check connectivity before wiring the lock factory
try (Connection c = DriverManager.getConnection(jdbcUrl, user, pass)) { /* ok */ }
TableMaintenance.forTable(table).lockFactory(JdbcLockFactory.builder().setJdbcUrl(jdbcUrl).build()); Defensive patterns
Strategy: try-catch
Validate before calling
try (Connection c = DriverManager.getConnection(jdbcUrl, user, pass)) {
try (Statement s = c.createStatement()) { s.execute("SELECT 1 FROM trigger_lock LIMIT 1"); }
} Try / catch
try {
factory.tryLock(...);
} catch (UncheckedSQLException e) {
LOG.error("JDBC lock check failed", e.getCause());
// fall back: skip maintenance this cycle
} Prevention
- Create/verify the JDBC lock table before enabling trigger locking
- Test JDBC URL and credentials with a SQL client from the Flink host
- Grant SELECT/INSERT/UPDATE/DELETE on the lock table to the JDBC user
- Monitor DB availability and set sane connection/socket timeouts
When it happens
Trigger: tryLock() -> isHeld() executing SELECT against the JDBC lock table fails with a SQLException: bad JDBC URI, database down, table missing (schema not initialized), credentials revoked, or connection dropped mid-query.
Common situations: JDBC catalog database restarted or unreachable during maintenance trigger creation; lock table dropped/recreated; network partition between Flink task manager and the RDS/Postgres host; wrong username/password in the JDBC connection config.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- Failed to remove lock %s
- Interrupted during unlock
- Failed to get lock information for %s
- Failed to check the state of the lock %s
- Failed to remove lock %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ff6c30827255e4de.
Report an issue: GitHub.