apache/iceberg · info · UncheckedInterruptedException
Interrupted during unlock
Error message
Interrupted during unlock
What it means
Thrown by JdbcLock.unlock when the thread is interrupted while the DELETE (or lock-info read/update) that releases the maintenance lock is running. The interrupt flag is restored and the InterruptedException is wrapped in UncheckedInterruptedException. The lock release may not have completed — check the lock table state.
Source
Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/maintenance/api/JdbcLockFactory.java:270
conn -> {
try (PreparedStatement sql = conn.prepareStatement(DELETE_LOCK_SQL)) {
sql.setString(1, type.key);
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);View on GitHub (pinned to 86d9c8fc54)
Solutions
- Expected during cancellation, but verify afterwards that the lock row was deleted to avoid a stale lock
- If a stale lock remains, delete it manually from the lock table before the next maintenance run
- If unexpected, find the interrupt source and adjust task lifecycle/shutdown ordering
- Respect the restored interrupt flag in surrounding code
Example fix
// after catching during shutdown, clean up any stale lock
try {
lock.unlock();
} catch (UncheckedInterruptedException e) {
Thread.currentThread().interrupt();
jdbcCleanup.deleteStaleLockRow(lockId); // avoid orphaned lock
} Defensive patterns
Strategy: try-catch
Try / catch
try {
lock.unlock();
} catch (UncheckedInterruptedException e) {
Thread.currentThread().interrupt();
// schedule a stale-lock sweep; release may not have completed
} Prevention
- After any interrupted unlock, sweep the lock table for rows owned by the dead instance
- Order shutdown so unlock completes before aggressive cancellation
- Use lock rows with timestamps so stale locks are easy to identify and purge
When it happens
Trigger: unlock is called (normally when the maintenance task closes) and the thread is interrupted mid SQL execution — task cancellation or Flink failover during close().
Common situations: Flink cancels the job while close() releases the lock; shutdownNow on the executor during unlock; failover racing with lock release.
Related errors
- Interrupted during tryLock
- Interrupted during isHeld
- Failed to remove lock %s
- Interrupted during unlock
- Interrupted in call to initialize
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/4846f8b1c36e8e34.
Report an issue: GitHub.