{"record":{"id":"467e04912d49597e","repo":"aeron-io/aeron","slug":"unexpected-interrupt-aeroncluster","errorCode":null,"errorMessage":"unexpected interrupt","messagePattern":"unexpected interrupt","errorType":"exception","errorClass":"AeronException","httpStatus":null,"severity":"error","filePath":"aeron-cluster/src/main/java/io/aeron/cluster/client/AeronCluster.java","lineNumber":2349,"sourceCode":"                    \" ingressEndpoints=\" + ctx.ingressEndpoints() +\n                    \" ingressPublication=\" + ingressPublication +\n                    \" egress.isConnected=\" + isConnected +\n                    \" responseChannel=\" + egressChannel);\n\n                for (final MemberIngress member : memberByIdMap.values())\n                {\n                    if (null != member.publicationException)\n                    {\n                        ex.addSuppressed(member.publicationException);\n                    }\n                }\n\n                throw ex;\n            }\n\n            if (Thread.currentThread().isInterrupted())\n            {\n                throw new AeronException(\"unexpected interrupt\");\n            }\n        }\n\n        private void createEgressSubscription()\n        {\n            if (NULL_VALUE == egressRegistrationId)\n            {\n                egressRegistrationId = ctx.aeron().asyncAddSubscription(ctx.egressChannel(), ctx.egressStreamId());\n            }\n\n            try\n            {\n                egressSubscription = ctx.aeron().getSubscription(egressRegistrationId);\n            }\n            catch (final RegistrationException ex)\n            {\n                egressRegistrationId = NULL_VALUE;\n","sourceCodeStart":2331,"sourceCodeEnd":2367,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-cluster/src/main/java/io/aeron/cluster/client/AeronCluster.java#L2331-L2367","documentation":"During AeronCluster.connect(), the blocking await helper rethrows checked exceptions and then checks the thread's interrupt flag. If the thread was interrupted while blocked, it throws AeronException('unexpected interrupt') because connect() does not support interruption and cannot complete safely with an unclear interruption state.","triggerScenarios":"Thread.interrupt() (or executor shutdownNow) hitting the thread inside AeronCluster.connect()'s busy-spin wait loop.","commonSituations":"Application shutdown calling executorService.shutdownNow() while a client thread is connecting; timeout watchdogs interrupting slow connects; container lifecycle hooks interrupting initialization.","solutions":["Avoid interrupting threads while AeronCluster.connect() is in flight; complete or cancel the connect before shutdown","Run connect() on a thread not managed by the shutting-down executor, and close the cluster client via aeronCluster.close()","If interruption is expected, catch AeronException around connect() and treat it as connect failure/cleanup"],"exampleFix":"// before\nexecutor.shutdownNow(); // interrupts in-flight connect()\n// after\nclusterClient.close();          // cancel connect/close first\nexecutor.shutdownNow();","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    AeronCluster cluster = AeronCluster.connect(ctx);\n} catch (AeronException e) {\n    if (Thread.currentThread().isInterrupted()) {\n        Thread.currentThread().interrupt(); // restore flag, treat as cancelled connect\n        return;\n    }\n    throw e;\n}","preventionTips":["Do not call shutdownNow() on executors running AeronCluster.connect()","Close cluster clients explicitly via aeronCluster.close() during shutdown","Run connect() on a dedicated thread insulated from interrupt-based cancellation"],"tags":["threading","interrupt","lifecycle"],"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"}