{"record":{"id":"79d595d36ec72230","repo":"microsoft/FASTER","slug":"unexpected-sealed-buffer-found","errorCode":null,"errorMessage":"Unexpected sealed buffer found","messagePattern":"Unexpected sealed buffer found","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"cs/remote/src/FASTER.common/ElasticCircularBuffer.cs","lineNumber":130,"sourceCode":"        public void Enqueue(ref T value)\n        {\n            if (tail.Value.IsFull())\n            {\n                tail.Value.Sealed = true;\n                var next = tail.Next;\n                if (next == null) next = buffers.First;\n                if (next.Value.Sealed)\n                {\n                    next = new LinkedListNode<CircularBuffer<T>>(new CircularBuffer<T>());\n                    buffers.AddAfter(tail, next);\n                }\n                next.Value.Enqueue(ref value);\n                tail = next;\n            }\n            else\n            {\n                if (tail.Value.Sealed)\n                    throw new Exception(\"Unexpected sealed buffer found\");\n                tail.Value.Enqueue(ref value);\n            }\n        }\n\n        /// <summary>\n        /// Enqueue\n        /// </summary>\n        /// <param name=\"value\"></param>\n        public void Enqueue(T value)\n        {\n            Enqueue(ref value);\n        }\n\n        /// <summary>\n        /// Dequeue\n        /// </summary>\n        /// <returns></returns>\n        [MethodImpl(MethodImplOptions.AggressiveInlining)]","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/microsoft/FASTER/blob/321d872eabda6a0345c8bd76419f89723ed864ae/cs/remote/src/FASTER.common/ElasticCircularBuffer.cs#L112-L148","documentation":"In the elastic (multi-segment) Enqueue, when the current segment is full the library moves to the next buffer; if that tail buffer is marked Sealed (drained/inactive), enqueueing into it would corrupt the ring's lifecycle invariants. The library throws instead of proceeding, signaling a bug in segment sealing/rotation logic or concurrent misuse of the buffer.","triggerScenarios":"Concurrent Enqueue/Dequeue from multiple threads without synchronization causing segment rotation to race; enqueuing after a segment was sealed but before a new one is linked; corrupt internal buffer list state.","commonSituations":"Using the elastic circular buffer as a lock-free queue from multiple producer threads when it is not safe for that pattern; mixing elastic and single-buffer APIs on the same instance.","solutions":["Synchronize all Enqueue/Dequeue access with a lock or use only from a single thread per direction.","Inspect and fix custom modifications to segment sealing/rotation logic if you maintain a fork.","Recreate the buffer instance if it entered a bad state; do not attempt to continue after this exception."],"exampleFix":"// before: concurrent producers\nqueue.Enqueue(ref item); // from many threads\n\n// after\nlock (queueLock) { queue.Enqueue(ref item); }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { elasticQueue.Enqueue(ref item); }\ncatch (Exception ex) when (ex.Message == \"Unexpected sealed buffer found\")\n{\n    // buffer lifecycle is corrupted; rebuild the queue and report\n    log.Fatal(ex, \"ElasticCircularBuffer invariants violated\");\n    elasticQueue = new ElasticCircularBuffer<T>();\n}","preventionTips":["Do not share the elastic buffer across producer threads without a lock.","Never mix single-buffer and elastic APIs on one instance.","If you fork the library, add tests around segment sealing/rotation.","Treat this exception as a bug signal, not a routine capacity event."],"tags":["csharp","buffer","concurrency","invariant","faster"],"backgroundTag":"internal-invariant-violation","analyzedSha":"321d872eabda6a0345c8bd76419f89723ed864ae","analyzedAt":"2026-09-15T22:18:00.693Z","contentChangedAt":"2026-09-15T22:18:00.693Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}