{"record":{"id":"37f05bd1d63fe39c","repo":"aeron-io/aeron","slug":"concurrentconcludeexception","errorCode":null,"errorMessage":"ConcurrentConcludeException","messagePattern":"ConcurrentConcludeException","errorType":"validation","errorClass":"ConcurrentConcludeException","httpStatus":null,"severity":"error","filePath":"aeron-archive/src/main/java/io/aeron/archive/client/PersistentSubscription.java","lineNumber":1677,"sourceCode":"            try\n            {\n                return (Context)super.clone();\n            }\n            catch (final CloneNotSupportedException ex)\n            {\n                throw new RuntimeException(ex);\n            }\n        }\n\n        /**\n         * Conclude configuration by setting up defaults when specifics are not provided.\n         */\n        @SuppressWarnings(\"MethodLength\")\n        public void conclude()\n        {\n            if ((boolean)IS_CONCLUDED_VH.getAndSet(this, true))\n            {\n                throw new ConcurrentConcludeException();\n            }\n\n            if (Aeron.NULL_VALUE == recordingId)\n            {\n                throw new ConfigurationException(\"recordingId must be set\");\n            }\n\n            if (Aeron.NULL_VALUE == liveStreamId)\n            {\n                throw new ConfigurationException(\"liveStreamId must be set\");\n            }\n\n            if (Strings.isEmpty(liveChannel))\n            {\n                throw new ConfigurationException(\"liveChannel must be set\");\n            }\n\n            if (Strings.isEmpty(replayChannel))","sourceCodeStart":1659,"sourceCodeEnd":1695,"githubUrl":"https://github.com/aeron-io/aeron/blob/6d60124e15e35c11b49ba2e3c2c2858a09a18803/aeron-archive/src/main/java/io/aeron/archive/client/PersistentSubscription.java#L1659-L1695","documentation":"PersistentSubscription.conclude() uses an atomic IS_CONCLUDED flag and throws ConcurrentConcludeException if conclude() is invoked when the subscription has already been (or is concurrently being) concluded. Conclude is a one-time initialization step; a second entry means a lifecycle bug in the calling code.","triggerScenarios":"Calling conclude() twice on the same PersistentSubscription.Builder, or calling it from two threads at once — e.g. an archive replay/connect path racing a manual conclude, or duplicated listener initialization callbacks.","commonSituations":"Frameworks or wrappers that both auto-conclude the builder and let user code conclude it; retry logic that re-runs an initialization routine containing conclude(); unsynchronized concurrent startup of a persistent subscription.","solutions":["Call conclude() exactly once per PersistentSubscription.Builder instance","Guard the initialization path with application-level synchronization or a once-flag if startup can race","Check for double-invocation from both framework auto-initialization and manual conclude() calls","If a retry restarts initialization, build a fresh Builder instead of reusing the concluded one"],"exampleFix":"// before\nbuilder.conclude();\n// ...retry path reuses same builder\nbuilder.conclude(); // ConcurrentConcludeException\n\n// after\nAtomicBoolean initialized = new AtomicBoolean();\nif (initialized.compareAndSet(false, true)) {\n    builder.conclude();\n}","handlingStrategy":"try-catch","validationCode":"AtomicBoolean concluded = new AtomicBoolean();\n// pre-check: only conclude if not already concluded\nif (!concluded.compareAndSet(false, true)) { skipConclude(); }","typeGuard":null,"tryCatchPattern":"try {\n    builder.conclude();\n} catch (ConcurrentConcludeException e) {\n    log.warn(\"subscription already concluded; ignoring duplicate conclude\", e);\n}","preventionTips":["Conclude exactly once per Builder; centralize subscription construction","Synchronize multi-threaded startup or use compareAndSet once-flags","Do not reuse a concluded Builder across retries — build a fresh one","Review framework hooks that may auto-conclude on your behalf"],"tags":["lifecycle","concurrency","initialization","aeron-archive"],"backgroundTag":"invalid-state-transition","analyzedSha":"6d60124e15e35c11b49ba2e3c2c2858a09a18803","analyzedAt":"2026-09-12T11:17:07.683Z","contentChangedAt":"2026-09-12T11:17:07.683Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}