apache/cassandra · error · IllegalStateException
Failed to acquire reference to compression dictionary
Error message
Failed to acquire reference to compression dictionary
What it means
When constructing CompressionMetadata for a table using compression dictionaries, buildCloseableArray() must acquire a reference to the dictionary via the dictionary manager. If the ref-counted acquisition returns null (dictionary unavailable/already evicted), the constructor cannot proceed; it closes the chunkOffsets memory first to avoid a leak and throws IllegalStateException.
Source
Thrown at src/java/org/apache/cassandra/io/compress/CompressionMetadata.java:171
this.compressedFileLength = compressedFileLength;
this.chunkOffsets = chunkOffsets;
this.chunkOffsetsSize = chunkOffsetsSize;
this.compressionDictionary = compressionDictionary;
}
private static AutoCloseable[] buildCloseableArray(Memory chunkOffsets, CompressionDictionary dictionary)
{
if (dictionary == null)
return new AutoCloseable[] { chunkOffsets };
Ref<? extends CompressionDictionary> dictRef = dictionary.tryRef();
if (dictRef == null)
{
// Close chunkOffsets before throwing to prevent resource leak.
// The CompressionMetadata constructor will not complete if we throw here,
// so we must clean up resources that were passed in.
chunkOffsets.close();
throw new IllegalStateException("Failed to acquire reference to compression dictionary");
}
return new AutoCloseable[] { chunkOffsets, dictRef::release };
}
/**
* Copy constructor for creating shared copies via sharedCopy().
* <br>
* This uses the WrappedSharedCloseable pattern where all copies share the same
* underlying resources (chunkOffsets Memory and dictionary reference). The super()
* call increments the shared reference count, and resources are only released when
* the last copy is closed.
* <br>
* Reference counting behavior:
* - Original CompressionMetadata acquires 1 dictionary reference (in buildCloseableArray)
* - All copies share that reference (via super(copy) incrementing shared ref count)
* - When last copy closes, WrappedSharedCloseable.Tidy releases the reference once
*/View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Restore/keep the compression dictionary files alongside the SSTables when copying or restoring data
- Check logs for dictionary manager/eviction errors and restart the node so dictionaries reload
- Rewrite the SSTables without dictionaries (disable compression dictionaries for the table, then scrub/upgrade-sstables) if dictionaries are unrecoverable
- If constructing metadata in code, close chunkOffsets on failure — or prefer the factory open() paths that handle teardown
Example fix
// before
CompressionMetadata m = new CompressionMetadata(file, len, useMmap); // throws if dict ref null
// after
try {
CompressionMetadata m = new CompressionMetadata(file, len, useMmap);
} catch (IllegalStateException e) {
logger.error("Dictionary unavailable for {}", file, e);
restoreDictionariesOrRewriteSSTable(file);
} Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure dictionary exists before constructing metadata
if (dictionaryManager != null && !dictionaryManager.contains(dictId))
throw new IllegalStateException("Dictionary missing: " + dictId); Try / catch
try { return new CompressionMetadata(file, len, useMmap); }
catch (IllegalStateException e) { closeQuietly(chunkOffsets); restoreDictionaryOrRewrite(); throw e; } Prevention
- Ship dictionary files with the SSTables they reference
- Disable compression dictionaries before removing dictionary files
- Test restore procedures to include dictionary directories
- Release dict refs promptly to avoid ref-count exhaustion
When it happens
Trigger: Creating CompressionMetadata via the constructor when CompressionDictionaryManager cannot supply an active reference for the dictionary id stored in the metadata — e.g. dictionary file removed, cache shut down, or ref-count lifecycle already released.
Common situations: Dictionary files deleted while SSTables referencing them remain; shutdown race where metadata is opened after dictionary manager closes; mismatched/moved dictionary storage after restoring from backup without the dictionary directory.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Failed to acquire reference to compression dictionary %s
- Failed adding SSTables
- Couldn't acquire reference to the SSTable {}. It may have be
- SASL negotiation not complete
- MBeanServer already initialized
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/4419fa448f5116a0.
Report an issue: GitHub.