{"record":{"id":"f188664f9e4055fb","repo":"apache/cassandra","slug":"dictionary-length-mismatch-for-s-dict-id-d-expe","errorCode":null,"errorMessage":"Dictionary length mismatch for %s dict id %d. Expected: %d, actual: %d","messagePattern":"Dictionary length mismatch for (.+?) dict id (.+?)\\. Expected: (.+?), actual: (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/compression/CompressionDictionary.java","lineNumber":309,"sourceCode":"    }\n\n    static CompressionDictionary createFromRow(UntypedResultSet.Row row)\n    {\n        String kindStr = row.getString(\"kind\");\n        long dictId = row.getLong(\"dict_id\");\n        byte[] dict = row.getByteArray(\"dict\");\n        int storedLength = row.getInt(\"dict_length\");\n        int storedChecksum = row.getInt(\"dict_checksum\");\n        Instant createdAt = row.getTimestamp(\"created_at\").toInstant();\n\n        try\n        {\n            Kind kind = CompressionDictionary.Kind.valueOf(kindStr);\n\n            // Validate length\n            if (dict.length != storedLength)\n            {\n                throw new IllegalStateException(String.format(\"Dictionary length mismatch for %s dict id %d. Expected: %d, actual: %d\",\n                                                              kindStr, dictId, storedLength, dict.length));\n            }\n\n            // Validate checksum\n            int calculatedChecksum = calculateChecksum((byte) kind.ordinal(), dictId, dict);\n            if (calculatedChecksum != storedChecksum)\n            {\n                throw new IllegalStateException(String.format(\"Dictionary checksum mismatch for %s dict id %d. Expected: %d, actual: %d\",\n                                                              kindStr, dictId, storedChecksum, calculatedChecksum));\n            }\n\n            return kind.createDictionary(new DictId(kind, dictId), row.getByteArray(\"dict\"), storedChecksum, createdAt);\n        }\n        catch (IllegalArgumentException ex)\n        {\n            throw new IllegalStateException(kindStr + \" compression dictionary is not created for dict id \" + dictId);\n        }\n    }","sourceCodeStart":291,"sourceCodeEnd":327,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/compression/CompressionDictionary.java#L291-L327","documentation":"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.","triggerScenarios":"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.","commonSituations":"Crashes during dictionary ingestion, manual tampering with system table data, storage corruption, or buggy upgrades that moved dictionary rows.","solutions":["Remove the inconsistent dictionary row so the system can create/fetch a fresh dictionary.","Regenerate the dictionary (re-run training) and re-ingest it.","Scrub/repair the system keyspace SSTables if corruption is suspected (nodetool scrub).","Investigate the write path or storage for why size metadata and blob diverged (check logs around dictionary creation time)."],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"// before trusting a dictionary row\nif (blob.length != row.getInt(\"size\"))\n    throw new IllegalStateException(\"stored size mismatch for dict id \" + row.getInt(\"dict_id\"));","typeGuard":null,"tryCatchPattern":"try {\n    d = createFromRow(row);\n} catch (IllegalStateException e) {\n    logger.warn(\"Discarding corrupt dictionary row: {}\", e.getMessage());\n    d = fallbackDictionary();\n}","preventionTips":["Never hand-edit system table rows","Run nodetool scrub/repair after unclean shutdowns","Compare size metadata and blob length in any tooling that copies dictionary rows"],"tags":["cassandra","compression","zstd-dictionary","corruption"],"backgroundTag":"checksum-mismatch","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}