apache/iceberg · error · UncheckedSQLException
Failed to remove lock
Error message
Failed to remove lock %s
What it means
unlock() in JdbcLockFactory hits a SQLException while reading or updating the lock rows in the JDBC catalog table, so the lock could not be removed. The original SQLException is wrapped in UncheckedSQLException and includes the lock's toString() (type and lockId) for diagnosis.
Solutions
- Check the wrapped SQLException cause for the root DB error (connectivity, missing table, permissions)
- Verify the JDBC connection is healthy and the lock table exists with the expected schema
- Retry the maintenance cycle; unlock failure typically leaves the lock for the next attempt
- Increase JDBC connection/validation timeouts if transient network issues are the cause
Example fix
// before
lockFactory.tryLock(); // UncheckedSQLException: Failed to remove lock
// after
try {
lockFactory.tryLock();
} catch (UncheckedSQLException e) {
LOG.error("Lock removal failed for {}", e.getCause(), e); // inspect root SQLException
} Defensive patterns
Strategy: retry
Validate before calling
// verify DB reachability before maintenance
try (Connection c = DriverManager.getConnection(jdbcUrl, user, pass)) { c.isValid(5); } Try / catch
try { lock.unlock(); } catch (UncheckedSQLException e) { LOG.error("unlock failed: {}", e.getCause()); /* retry next cycle */ } Prevention
- Keep the JDBC lock table schema in sync with the catalog version
- Monitor DB connectivity from Flink task managers
- Grant the lock-table user read/write/delete privileges
- Use a connection pool with validation queries
When it happens
Trigger: Calling JdbcLock.unlock() when the underlying SQL statements to fetch/update/delete the lock row fail: connection loss, table missing, constraint violation, or DB timeout.
Common situations: Database restarted or connection pool closed mid-maintenance; lock table schema mismatch after catalog upgrade; network partition to JDBC metastore; wrong jdbc catalog config pointing to a database without the lock table.
Related errors
- Failed to get lock information for
- Cannot check and eventually update SQL schema
- Cannot initialize JDBC catalog
- Cannot initialize JDBC table maintenance lock
- Cannot initialize JDBC table maintenance lock
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/3715c2d7f1fe1094.
Report an issue: GitHub.
Appendix: source
Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/JdbcLockFactory.java:273
sql.setString(2, lockId);
sql.setString(3, instanceId);
long count = sql.executeUpdate();
LOG.info(
"Deleted {} lock with instanceId {} with row count {}",
this,
instanceId,
count);
}
return null;
});
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new UncheckedInterruptedException(e, "Interrupted during unlock");
} catch (SQLException e) {
// SQL exception happened when getting/updating lock information
throw new UncheckedSQLException(e, "Failed to remove lock %s", this);
}
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this).add("type", type).add("lockId", lockId).toString();
}
@SuppressWarnings("checkstyle:NestedTryDepth")
private String instanceId() {
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()) {
if (rs.next()) {View on GitHub (pinned to 86d9c8fc54)