{"record":{"id":"cb74182df56e851b","repo":"apache/cassandra","slug":"already-released","errorCode":null,"errorMessage":"Already released","messagePattern":"Already released","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/net/ShareableBytes.java","lineNumber":136,"sourceCode":"            count = this.count;\n        }\n    }\n\n    public void release()\n    {\n        owner.doRelease();\n    }\n\n    private void doRelease()\n    {\n        int count = this.count;\n\n        if (count < 0)\n            countUpdater.lazySet(this, count += 1);\n        else if (count > 0)\n            count = countUpdater.decrementAndGet(this);\n        else\n            throw new IllegalStateException(\"Already released\");\n\n        if (count == RELEASED)\n            BufferPools.forNetworking().put(bytes);\n    }\n\n    boolean isReleased()\n    {\n        return owner.count == RELEASED;\n    }\n\n    /**\n     * Create a slice over the next {@code length} bytes, consuming them from our buffer, and incrementing the owner count\n     */\n    public ShareableBytes sliceAndConsume(int length)\n    {\n        int begin = bytes.position();\n        int end = begin + length;\n        ShareableBytes result = slice(begin, end);","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/net/ShareableBytes.java#L118-L154","documentation":"ShareableBytes.doRelease() decrements the reference count; when the count is already 0 (or the RELEASED sentinel) there is nothing to release, indicating an over-release bug, so it throws IllegalStateException. When the count reaches RELEASED the buffer is returned to the networking buffer pool.","triggerScenarios":"Calling release() more times than retain()/copies of the SharedBytes were handed out, or releasing the same ShareableBytes instance from two paths (e.g. both the frame reader and the consumer).","commonSituations":"Error-path cleanup that releases a buffer already released in the happy path; double release across async callbacks; connection teardown racing frame consumption.","solutions":["Audit ownership so exactly one path releases each reference exactly once","Guard with bytes.isReleased() before releasing on error/cleanup paths","Use try-finally so release happens on exactly one well-defined path"],"exampleFix":"// before\nfinally { shared.release(); }  // happy path also released\n// after\nif (!shared.isReleased()) shared.release();","handlingStrategy":"validation","validationCode":"if (!shared.isReleased()) shared.release();","typeGuard":null,"tryCatchPattern":"try { shared.release(); } catch (IllegalStateException e) { log.warn(\"Double release of SharedByteBuffer\", e); }","preventionTips":["Release each reference exactly once; avoid releasing in both error and success paths","Prefer try-finally around a single release point","Track ownership with explicit retain counts when sharing across async stages"],"tags":["network","buffer","reference-counting","double-release"],"backgroundTag":"invalid-state-transition","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}