google/guava · error · RuntimeException
Unexpected interrupt while waiting for latch
Error message
Unexpected interrupt while waiting for latch
What it means
GcFinalization.await(CountDownLatch) loops, calling System.gc() and latch.await(1, SECONDS) until the latch counts down or the deadline expires. An InterruptedException is treated as unexpected and rethrown wrapped in a RuntimeException, because the helper assumes the awaiting thread should not be cancelled mid-wait.
Source
Thrown at android/guava-testlib/src/com/google/common/testing/GcFinalization.java:226
*/
public static void await(CountDownLatch latch) {
if (latch.getCount() == 0) {
return;
}
long timeoutSeconds = timeoutSeconds();
long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds);
do {
runFinalization();
if (latch.getCount() == 0) {
return;
}
System.gc();
try {
if (latch.await(1L, SECONDS)) {
return;
}
} catch (InterruptedException ie) {
throw new RuntimeException("Unexpected interrupt while waiting for latch", ie);
}
} while (System.nanoTime() - deadline < 0);
throw formatRuntimeException(
"Latch failed to count down within %d second timeout", timeoutSeconds);
}
/**
* Creates a garbage object that counts down the latch in its finalizer. Sequestered into a
* separate method to make it somewhat more likely to be unreachable.
*/
private static void createUnreachableLatchFinalizer(CountDownLatch latch) {
FinalizableReference.register(new Object(), latch);
}
/**
* A predicate that is expected to return true subsequent to <em>finalization</em>, that is, one
* of the following actions taken by the garbage collector when performing a full collection in
* response to {@link System#gc()}:View on GitHub (pinned to 94f39958ba)
Solutions
- Ensure the thread running the await is not interrupted — widen test timeouts or move off interruptible threads.
- Make the latch count down promptly (release references fast) so await(1s) returns before any interrupt lands.
- If interruption is legitimate in your environment, do not use this helper; await the latch yourself and restore interrupt status on InterruptedException.
- Clear stray interrupt status (Thread.interrupted()) before calling await.
Example fix
// before GcFinalization.await(latch); // thread was interrupted -> RuntimeException // after Thread.interrupted(); // clear status GcFinalization.await(latch);
Defensive patterns
Strategy: try-catch
Validate before calling
// Clear stray interrupt status before awaiting the latch. Thread.interrupted(); assert !Thread.currentThread().isInterrupted(); GcFinalization.await(latch);
Try / catch
try {
GcFinalization.await(latch);
} catch (RuntimeException e) {
if (!(e.getCause() instanceof InterruptedException)) throw e;
Thread.currentThread().interrupt();
throw e;
} Prevention
- Do not run the latch await on interruptible test threads.
- Set test timeouts above the GcFinalization deadline.
- Clear stray interrupt status before calling await.
- Ensure the latch counts down promptly (release references quickly).
When it happens
Trigger: Calling GcFinalization.await(latch)/awaitFullGc() (latch variant) while the running thread is concurrently interrupted — test timeouts, executor shutdown, or harness cancellation.
Common situations: Test-framework timeouts interrupting the thread; finalizer-based tests where the latch is registered via FinalizableReference and the thread is cancelled before the latch counts down; stray interrupt status from prior tests.
Related errors
- Unexpected interrupt while waiting for future
- scheduleAtFixedRate is not supported.
- scheduleWithFixedDelay is not supported.
- %s returns null and cannot be used to test instance methods.
- at index %s
AI-assisted analysis of google/guava@94f39958ba (2026-08-13).
Data as JSON: /api/errors/040b2296512c45cf.
Report an issue: GitHub.