apache/cassandra · error · IllegalStateException

Dictionary length mismatch for %s dict id %d. Expected: %d,

Error message

Dictionary length mismatch for %s dict id %d. Expected: %d, actual: %d

What it means

createFromRow reconstructs a CompressionDictionary from the dictionary system table row. It validates that the actual byte[] length equals the stored length column before validating the checksum; a mismatch means the stored blob does not match its own metadata, indicating corruption, so an IllegalStateException is thrown.

Source

Thrown at src/java/org/apache/cassandra/db/compression/CompressionDictionary.java:309

    }

    static CompressionDictionary createFromRow(UntypedResultSet.Row row)
    {
        String kindStr = row.getString("kind");
        long dictId = row.getLong("dict_id");
        byte[] dict = row.getByteArray("dict");
        int storedLength = row.getInt("dict_length");
        int storedChecksum = row.getInt("dict_checksum");
        Instant createdAt = row.getTimestamp("created_at").toInstant();

        try
        {
            Kind kind = CompressionDictionary.Kind.valueOf(kindStr);

            // Validate length
            if (dict.length != storedLength)
            {
                throw new IllegalStateException(String.format("Dictionary length mismatch for %s dict id %d. Expected: %d, actual: %d",
                                                              kindStr, dictId, storedLength, dict.length));
            }

            // Validate checksum
            int calculatedChecksum = calculateChecksum((byte) kind.ordinal(), dictId, dict);
            if (calculatedChecksum != storedChecksum)
            {
                throw new IllegalStateException(String.format("Dictionary checksum mismatch for %s dict id %d. Expected: %d, actual: %d",
                                                              kindStr, dictId, storedChecksum, calculatedChecksum));
            }

            return kind.createDictionary(new DictId(kind, dictId), row.getByteArray("dict"), storedChecksum, createdAt);
        }
        catch (IllegalArgumentException ex)
        {
            throw new IllegalStateException(kindStr + " compression dictionary is not created for dict id " + dictId);
        }
    }

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Remove the inconsistent dictionary row so the system can create/fetch a fresh dictionary.
  2. Regenerate the dictionary (re-run training) and re-ingest it.
  3. Scrub/repair the system keyspace SSTables if corruption is suspected (nodetool scrub).
  4. Investigate the write path or storage for why size metadata and blob diverged (check logs around dictionary creation time).

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

// before trusting a dictionary row
if (blob.length != row.getInt("size"))
    throw new IllegalStateException("stored size mismatch for dict id " + row.getInt("dict_id"));

Try / catch

try {
    d = createFromRow(row);
} catch (IllegalStateException e) {
    logger.warn("Discarding corrupt dictionary row: {}", e.getMessage());
    d = fallbackDictionary();
}

Prevention

When it happens

Trigger: Reading a dictionary row where dict.length != storedLength — e.g. the blob column was truncated, updated without updating size metadata, or the row is corrupt.

Common situations: Crashes during dictionary ingestion, manual tampering with system table data, storage corruption, or buggy upgrades that moved dictionary rows.

Understand the failure class

Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.

Related errors


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