{"record":{"id":"3a11240c810ae741","repo":"aeron-io/aeron","slug":"unexpected-interrupt-commoncontext","errorCode":null,"errorMessage":"unexpected interrupt","messagePattern":"unexpected interrupt","errorType":"exception","errorClass":"AeronException","httpStatus":null,"severity":"warning","filePath":"aeron-client/src/main/java/io/aeron/CommonContext.java","lineNumber":1488,"sourceCode":"        {\n            return loggingErrorHandler;\n        }\n        else\n        {\n            return new ErrorHandlerWrapper(loggingErrorHandler, userErrorHandler);\n        }\n    }\n\n    static void sleep(final long durationMs)\n    {\n        try\n        {\n            Thread.sleep(durationMs);\n        }\n        catch (final InterruptedException ex)\n        {\n            Thread.currentThread().interrupt();\n            throw new AeronException(\"unexpected interrupt\", ex);\n        }\n    }\n\n    private static String cncFileErrorMessage(final File file, final Exception ex)\n    {\n        return \"cannot open CnC file: \" + file.getAbsolutePath() + \" reason=\" + ex;\n    }\n\n    private static final class ErrorHandlerWrapper implements ErrorHandler, AutoCloseable\n    {\n        private final LoggingErrorHandler loggingErrorHandler;\n        private final ErrorHandler userErrorHandler;\n\n        private ErrorHandlerWrapper(final LoggingErrorHandler loggingErrorHandler, final ErrorHandler userErrorHandler)\n        {\n            this.loggingErrorHandler = loggingErrorHandler;\n            this.userErrorHandler = userErrorHandler;\n        }","sourceCodeStart":1470,"sourceCodeEnd":1506,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-client/src/main/java/io/aeron/CommonContext.java#L1470-L1506","documentation":"CommonContext.sleep is a helper that pauses the calling thread; if Thread.sleep is interrupted, the interrupt flag is restored and an AeronException('unexpected interrupt') is thrown with the InterruptedException as cause, because nothing in driver-await logic expects interruption.","triggerScenarios":"Shutting down or interrupting the thread that is calling Aeron.connect() / driver-awaiting code while it is inside a sleep between CnC polling attempts.","commonSituations":"Application shutdown ExecutorService.shutdownNow interrupting a connecting thread; timeouts that cancel/interrupt connect attempts; test frameworks interrupting threads between tests.","solutions":["Avoid interrupting threads that are connecting to Aeron; let the connect attempt finish or use a shorter driver timeout","Catch AeronException at shutdown and treat it as an aborted connect","If interruption is expected in your design, wrap connect in code that handles AeronException cause InterruptedException"],"exampleFix":"// before\nexecutor.shutdownNow(); // interrupts thread inside Aeron.connect()\n\n// after\nCompletableFuture<Aeron> connecting = CompletableFuture.supplyAsync(() -> Aeron.connect(ctx));\nconnecting.cancel(false); // let it finish instead of interrupting, or join with timeout first","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { Aeron aeron = Aeron.connect(ctx); } catch (AeronException e) { if (e.getMessage().equals(\"unexpected interrupt\") && e.getCause() instanceof InterruptedException) { Thread.currentThread().interrupt(); /* treat as cancelled connect */ } else { throw e; } }","preventionTips":["Don't shutdownNow()/interrupt threads while they are inside Aeron.connect()","Use short driver timeouts rather than interruption to bound connect time","Restore the interrupt status when handling this exception at shutdown"],"tags":["aeron","interrupt","threading","shutdown"],"backgroundTag":"thread-interrupted","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}