apache/cassandra · error · java.lang.IllegalStateException

Table's compressor can not accept any dictionary:

Error message

Table's compressor can not accept any dictionary: 

What it means

CQLSSTableWriter.build() validates that, when a compression dictionary was supplied to the writer, the table's compression params actually enable dictionary-based compression. If the compressor is not dictionary-enabled, Cassandra cannot attach the dictionary to the SSTables it writes, so it fails fast with an IllegalStateException containing the compression params map. This prevents silently writing SSTables without the requested dictionary.

Source

Thrown at src/java/org/apache/cassandra/io/sstable/CQLSSTableWriter.java:763

                    {
                        // we need to commit keyspace metadata first so applyIndexes sees that keyspace from TCM
                        commitKeyspaceMetadata(ksm.withSwapped(ksm.tables.with(tableMetadata)));
                        applyIndexes(keyspaceName);
                    }

                    KeyspaceMetadata keyspaceMetadata = ClusterMetadata.current().schema.getKeyspaceMetadata(keyspaceName);
                    tableMetadata = keyspaceMetadata.tables.getNullable(tableName);

                    Schema.instance.submit(SchemaTransformations.addTable(tableMetadata, true));
                }

                if (compressionDictionary != null)
                {
                    CompressionParams compressionParams = tableMetadata.params.compression;

                    if (!compressionParams.isDictionaryCompressionEnabled())
                    {
                        throw new IllegalStateException("Table's compressor can not accept any dictionary: " + compressionParams.asMap());
                    }

                    IDictionaryCompressor compressor = (IDictionaryCompressor) compressionParams.getSstableCompressor();
                    if (!compressor.canConsumeDictionary(compressionDictionary))
                    {
                        throw new IllegalStateException("Provided dictionary can not be consumed by table's compressor. " +
                                                        "Provided dictionary type: " + compressionDictionary.kind() +
                                                        "; expected dictionary type by the compressor: " + compressor.acceptableDictionaryKind());
                    }
                }

                ColumnFamilyStore cfs = null;
                if ((buildIndexes && !indexStatements.isEmpty()) || compressionDictionary != null)
                {
                    KeyspaceMetadata keyspaceMetadata = ClusterMetadata.current().schema.getKeyspaceMetadata(keyspaceName);
                    Keyspace keyspace = Keyspace.mockKS(keyspaceMetadata);
                    Directories directories = new Directories(tableMetadata, Collections.singleton(new Directories.DataDirectory(new File(directory.toPath()))));
                    cfs = ColumnFamilyStore.createColumnFamilyStore(keyspace,

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Enable dictionary compression on the table, e.g. CREATE/ALTER the table with compression {'class': 'ZstdCompressor', 'zstd_dictionary': ...} or the dictionary-enabled compression option before building the writer
  2. Remove the compressionDictionary option from the CQLSSTableWriter builder so validation passes for a non-dictionary compressor
  3. Inspect compressionParams.asMap() in the message to confirm which compression class is configured and switch to IDictionaryCompressor-based settings

Example fix

// before
CQLSSTableWriter writer = CQLSSTableWriter.builder()
    .inTable(table)
    .withCompressionDictionary(dict)
    .forTable("CREATE TABLE ks.t (...) WITH compression = {'class': 'LZ4Compressor'};")
    .build();
// after
CQLSSTableWriter writer = CQLSSTableWriter.builder()
    .inTable(table)
    .withCompressionDictionary(dict)
    .forTable("CREATE TABLE ks.t (...) WITH compression = {'class': 'ZstdCompressor', 'compression_dictionary': '...'};")
    .build();
Defensive patterns

Strategy: validation

Validate before calling

CompressionParams cp = tableMetadata.params.compression;
if (dict != null && !(cp.getSstableCompressor() instanceof IDictionaryCompressor))
    throw new IllegalStateException("Dictionary given but compressor is not dictionary-capable: " + cp.asMap());

Type guard

boolean canUseDict = dict != null
    && tableMetadata.params.compression.isDictionaryCompressionEnabled()
    && tableMetadata.params.compression.getSstableCompressor() instanceof IDictionaryCompressor;

Try / catch

try (CQLSSTableWriter w = builder.build()) { ... }
catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Table's compressor can not accept any dictionary"))
        // fix schema compression options or drop the dictionary option
}

Prevention

When it happens

Trigger: Calling CQLSSTableWriter.builder() with .withCompressionDictionary(...) (or an equivalent option) while the table schema's CompressionParams do not have dictionary compression enabled (e.g. using a plain compressor like LZ4/Snappy/Deflate instead of a dictionary compressor such as Zstd with dictionary support).

Common situations: Scripts that bulk-load SSTables with offline compression dictionaries against tables whose CREATE TABLE compression options were copied from a non-dictionary template; upgrading schemas where compression options were reverted; mixing writer options from one cluster's schema with another table's.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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