apache/cassandra · warning
Failed to close ZstdDictCompress
Error message
Failed to close ZstdDictCompress
What it means
Logged by ZstdCompressionDictionary's Tidyable/Ref tidy method when closing the per-thread ZstdDictCompress native resource throws an exception. The code deliberately swallows the exception and logs a warning so the remaining resources (per-level dicts, decompression dict) still get closed. It signals a native zstd dictionary was not cleanly released, potentially leaking native memory.
Solutions
- Treat a single occurrence as benign noise unless accompanied by native memory growth (check Native/ByteBuf memory metrics).
- If repeated, verify the zstd JNI/native library version bundled with Cassandra matches the release (no mixed libzstd on the system library path).
- Check for concurrent access to the dictionary during close (ensure the dictionary is truly unreferenced; avoid manually dropping refs).
- If native memory leaks correlate with these warnings, capture logs and report to the project; restart affected node to reclaim leaked native memory.
Defensive patterns
Strategy: try-catch
Try / catch
try {
dict.close();
} catch (Exception e) {
logger.warn("Failed to close ZstdDictCompress", e); // swallow, continue cleanup
} Prevention
- Monitor native (non-heap) memory for growth after these warnings.
- Avoid manually forcing dictionary eviction; let reference counting drive cleanup.
- Keep Cassandra's bundled zstd native library path clean of conflicting system libzstd.
- Alert on repetition rate, not single occurrences.
When it happens
Trigger: A compressed sstable's shared compression dictionary is being discarded (table drop, sstable compaction, dictionary replacement) and ZstdDictCompress.close() on the underlying zstd native handle throws; JVM shutdown or cache eviction triggers tidy on a dictionary whose native buffer was already freed or is in use.
Common situations: Table drops with zstd dictionary compression; heavy compaction activity churning dictionaries; native library state inconsistencies after close attempts; monitoring native memory leaks after such warnings.
Related errors
- Failed to close ZstdDictDecompress
- Error notifying dictionary trained listener for
- Failed to create for . , reason
- compressed_read_ahead_buffer_size must be at least 256KiB…
- Compression dictionary checksum does not match. Expected
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/d29ede5fa4c11f90.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/db/compression/ZstdCompressionDictionary.java:281
* 3. Once refcount is negative, tryRef() returns null, preventing new references
*
* Therefore, no synchronization is needed - we have exclusive access to clean up.
*/
@Override
public void tidy()
{
// Close all compression dictionaries
// No synchronization needed - reference counting ensures exclusive access
for (ZstdDictCompress compressDict : zstdDictCompressPerLevel.values())
{
try
{
compressDict.close();
}
catch (Exception e)
{
// Log but don't fail - continue closing other resources
logger.warn("Failed to close ZstdDictCompress", e);
}
}
zstdDictCompressPerLevel.clear();
// Close decompression dictionary
ZstdDictDecompress decompressDict = dictDecompress.get();
if (decompressDict != null)
{
try
{
decompressDict.close();
}
catch (Exception e)
{
logger.warn("Failed to close ZstdDictDecompress", e);
}
dictDecompress.set(null);
}View on GitHub (pinned to 88fd0f6a0e)