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
- 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
- Remove the compressionDictionary option from the CQLSSTableWriter builder so validation passes for a non-dictionary compressor
- 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
- Verify the table's compression class supports dictionaries before passing a dictionary
- Keep table DDL and writer dictionary options in sync in load scripts
- Log compressionParams.asMap() during load-script setup
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
- No SSTables available for training in table <keyspaceName>.<
- stream can only move forward
- Cannot create CompressionParams for stored parameters
- Invalid negative chunk index %d with position %d
- Invalid number of arguments, expecting %d values but got %d
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/989ab758a7bc78e7.
Report an issue: GitHub.