apache/cassandra · warning
Attempted to release storage-attached index segment builder
Error message
Attempted to release storage-attached index segment builder memory after builder marked inactive.
What it means
This warning is logged by SegmentBuilder.release when release() is called on a builder whose active flag is already false, meaning its memory was already released against the SAI memory limiter and ACTIVE_BUILDER_COUNT was already decremented. The call is a no-op (it just returns the limiter's current usage), but it signals a double-release or a release after the builder was already finalized during flush. Memory accounting remains correct; the warning is a lifecycle-management bug signal.
Source
Thrown at src/java/org/apache/cassandra/index/sai/disk/v1/segment/SegmentBuilder.java:242
* This method does three things:
* <p>
* 1. It decrements active builder count and updates the global minimum flush size to reflect that.
* 2. It releases the builder's memory against its limiter.
* 3. It defensively marks the builder inactive to make sure nothing bad happens if we try to close it twice.
*
* @return the number of bytes used by the memory limiter after releasing this builder
*/
public long release()
{
if (active)
{
minimumFlushBytes = limiter.limitBytes() / ACTIVE_BUILDER_COUNT.getAndDecrement();
long used = limiter.decrement(totalBytesAllocated);
active = false;
return used;
}
logger.warn(index.identifier().logMessage("Attempted to release storage-attached index segment builder memory after builder marked inactive."));
return limiter.currentBytesUsed();
}
public abstract boolean isEmpty();
protected abstract long addInternal(ByteBuffer term, int segmentRowId);
protected abstract SegmentMetadata.ComponentMetadataMap flushInternal(IndexDescriptor indexDescriptor) throws IOException;
public int getRowCount()
{
return rowCount;
}
/**
* @return true if next SSTable row ID exceeds max segment row ID
*/
public boolean exceedsSegmentLimit(long ssTableRowId)View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Guard the release call with an ownership/flag in the caller so release() runs exactly once (or rely on the builder's own active flag as the guard)
- Audit the flush/close path so release happens in a single finally block per builder rather than from multiple cleanup sites
- If reproducible after an upgrade, rebuild the index and report with a thread dump/stack trace to the Cassandra community as a possible lifecycle bug
Example fix
// before
segmentBuilder.release();
segmentBuilder.release(); // double release in error path
// after
if (segmentBuilder != null && released.compareAndSet(false, true))
segmentBuilder.release(); Defensive patterns
Strategy: validation
Validate before calling
// check before releasing
if (segmentBuilder.isActive())
segmentBuilder.release(); Prevention
- Call release() exactly once per builder, from a single owner in a finally block
- Never call release() after flush()/close() has completed
- Add an idempotency flag in caller code when multiple cleanup paths exist
- Watch SAI memory-limiter accounting in logs; repeated double-release warnings indicate a lifecycle bug to fix
When it happens
Trigger: Calling release() twice on the same SegmentBuilder, or calling release() after flush completed and the builder was already marked inactive; typically from index builder cleanup paths racing with the flush-and-release sequence.
Common situations: A failed or retried flush path where cleanup code runs both in an error handler and in the normal close path; concurrent index drops during flush causing duplicate release calls; custom patches or upgrades where the builder lifecycle ordering changed.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- An error occurred while scrubbing the partition with key '%s
- Storage-attached index is no longer queryable. Please restar
- {} failed for index component {} on SSTable {}
- No rows to index during flush of SSTable {}.
- Failed to update per-column components for SSTable {}
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/8583946c378af536.
Report an issue: GitHub.