apache/cassandra · warning

Failed to release compression dictionary

Error message

Failed to release compression dictionary {}

What it means

This log warning comes from the removal listener of the compression-dictionary cache: when a dictionary entry is evicted, closing the dictionary's shared ref failed with an exception. The eviction still happens; only resource cleanup of the dictionary (its Ref/selfRef) failed, potentially leaking off-heap resources.

Solutions

  1. Inspect the logged stack trace for the underlying close() failure (usually a StrRef already-closed IllegalStateException).
  2. Check whether the table was dropped/disabled concurrently and avoid racing disable-dictionary with heavy read traffic.
  3. If ref leaks recur, report/fix the close idempotency in CompressionDictionary; the warning itself needs no client action.
Defensive patterns

Strategy: try-catch

Try / catch

// operator-side: watch logs for this warning and the nested exception
if (log.contains("Failed to release compression dictionary")) {
    inspectStackTrace(log); // determine double-close vs leak
}

Prevention

When it happens

Trigger: Cache eviction triggers dictionary.close() whose underlying shared ref is already closed or throws; logged with the dictId and the exception as a warn in the cache constructor's removalListener.

Common situations: Double-close races during aggressive cache churn; dictionary refs invalidated by table drop while entries are being evicted.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/4cb242f6c9b5cf3b. Report an issue: GitHub.

Appendix: source

Thrown at src/java/org/apache/cassandra/db/compression/CompressionDictionaryCache.java:81

        this.cache = Caffeine.newBuilder()
                             .maximumSize(maximumSize)
                             .expireAfterAccess(Duration.ofSeconds(expireAfterSeconds))
                             .removalListener((DictId dictId,
                                               CompressionDictionary dictionary,
                                               RemovalCause cause) -> {
                                 // Release the cache's reference to the dictionary when evicted
                                 // The dictionary will only be truly cleaned up when all references are released
                                 if (dictionary != null)
                                 {
                                     try
                                     {
                                         // The dictionary's selfRef should never be null when evicting from cache
                                         // but using close() to have better resiliency
                                         dictionary.close();
                                     }
                                     catch (Exception e)
                                     {
                                         logger.warn("Failed to release compression dictionary {}", dictId, e);
                                     }
                                 }
                             })
                             .executor(ImmediateExecutor.INSTANCE)
                             .build();
    }

    @Nullable
    @Override
    public CompressionDictionary getCurrent()
    {
        DictId dictId = currentDictId.get();
        return dictId == null ? null : get(dictId);
    }

    @Nullable
    @Override
    public CompressionDictionary get(DictId dictId)

View on GitHub (pinned to 88fd0f6a0e)