apache/flink · warning · IOException

interrupted while acquiring lock

Error message

interrupted while acquiring lock

What it means

lock() uses lockInterruptibly(); if the thread is interrupted while waiting for the stream's reentrant lock, it re-asserts the interrupt flag and wraps the failure in IOException("interrupted while acquiring lock"). This makes interruption visible to Flink's I/O error handling instead of being swallowed inside a lock acquisition.

Source

Thrown at flink-filesystems/flink-s3-fs-native/src/main/java/org/apache/flink/fs/s3native/writer/NativeS3RecoverableFsDataOutputStream.java:315

                            key,
                            uploadId,
                            e);
                }
                if (cleanupException != null) {
                    throw cleanupException;
                }
            }
        } finally {
            unlock();
        }
    }

    private void lock() throws IOException {
        try {
            lock.lockInterruptibly();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new IOException("interrupted while acquiring lock", e);
        }
    }

    private void unlock() {
        lock.unlock();
    }
}

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Treat this as expected during cancellation: catch IOException in shutdown paths, check Thread.currentThread().isInterrupted(), and exit cleanly.
  2. Avoid sharing the stream across threads — confine it to one thread/actor to remove lock contention entirely.
  3. Ensure any code that catches this exception does not mask the interrupt flag (the stream already re-set it; propagate or honor it).
  4. If seen outside cancellation, look for long lock holders (slow uploads inside write) and shorten critical sections.

Example fix

// before
catch (IOException e) { log.error("write failed", e); }

// after
catch (IOException e) {
    if (Thread.currentThread().isInterrupted()) {
        // job is being cancelled — release resources quietly
        return;
    }
    throw e;
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
    stream.write(...);
} catch (IOException e) {
    if (Thread.currentThread().isInterrupted()) {
        // cancellation in progress — unwind quietly
        return;
    }
    throw e;
}

Prevention

When it happens

Trigger: Two threads use the stream (one holds the lock in write/flush/commit), and the waiting thread is interrupted — job cancellation is the canonical case: Flink interrupts task threads on cancel while another thread holds the stream lock.

Common situations: Job cancellation during heavy S3 upload activity; failover racing a concurrent flush; user code sharing one recoverable stream across a timer thread and the mailbox thread.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/2999be4c7266dee4. Report an issue: GitHub.