apache/iceberg · error · UncheckedSQLException
Failed to get lock information for %s
Error message
Failed to get lock information for %s
What it means
JdbcLockFactory.instanceId() could not read/write lock information in the JDBC lock table while computing a unique instance id; the SQLException is wrapped into UncheckedSQLException with this message. No instance id could be established, so trigger locking cannot proceed.
Source
Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/JdbcLockFactory.java:303
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()) {
if (rs.next()) {
return rs.getString(1);
} else {
return null;
}
}
}
});
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new UncheckedInterruptedException(e, "Interrupted during unlock");
} catch (SQLException e) {
throw new UncheckedSQLException(e, "Failed to get lock information for %s", type);
}
}
}
private enum Type {
MAINTENANCE("m"),
RECOVERY("r");
private final String key;
Type(String key) {
this.key = key;
}
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Create the JDBC lock table with the schema expected by JdbcCatalog/JdbcLockFactory before enabling maintenance.
- Validate JDBC URL, user and password against the target database with a SQL client.
- Grant the JDBC user SELECT/INSERT/UPDATE/DELETE on the lock table.
- Retry startup if concurrent instance allocation caused a transient conflict; stagger task manager starts.
- Read UncheckedSQLException.getCause() for the exact driver error message.
Example fix
// before
JdbcLockFactory.builder().setJdbcUrl("jdbc:postgresql://host:5432/iceberg") // lock table never created
.build();
// after
// run first: CREATE TABLE iceberg.maintenance_lock (...) per JdbcCatalog docs
JdbcLockFactory.builder().setJdbcUrl("jdbc:postgresql://host:5432/iceberg").build(); Defensive patterns
Strategy: validation
Validate before calling
try (Connection c = DriverManager.getConnection(jdbcUrl, user, pass)) {
DatabaseMetaData md = c.getMetaData();
if (!md.getTables(null, null, "trigger_lock", null).next()) {
throw new IllegalStateException("Lock table missing - run init SQL");
}
} Try / catch
try {
factory.tableTriggerLock(...);
} catch (UncheckedSQLException e) {
LOG.error("instanceId allocation failed", e.getCause());
// retry with backoff once the DB/table is fixed
} Prevention
- Create the lock table before first maintenance run
- Grant full DML on the lock table to the JDBC user
- Verify database name in the JDBC URL exists
- Stagger concurrent task-manager startups to avoid lock-row races
When it happens
Trigger: SQLException during instanceId()'s lock-table access: database unreachable, lock table missing, INSERT/SELECT denied, or duplicate/unique-key conflict on lock rows during concurrent startup.
Common situations: First run before the lock table was created; two task managers starting concurrently against a DB with restrictive isolation; credentials valid for SELECT but not INSERT; JDBC URL pointing at a nonexistent database.
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 check the state of the lock %s
- Failed to remove lock %s
- Failed to check the state of the lock %s
- Failed to remove lock %s
- Failed to get lock information for %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/8002fd59ad619603.
Report an issue: GitHub.