{"record":{"id":"03d3fe40f743b4bb","repo":"apache/cassandra","slug":"corrupt-hintsdescriptor-serialization-problem","errorCode":null,"errorMessage":"Corrupt HintsDescriptor serialization, problem: ","messagePattern":"Corrupt HintsDescriptor serialization, problem: ","errorType":"exception","errorClass":"MarshalException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/hints/HintsDescriptor.java","lineNumber":480,"sourceCode":"        validateCRC(in.readInt(), (int) crc.getValue());\n\n        return new HintsDescriptor(hostId, version, timestamp, decodeJSONBytes(paramsBytes));\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private static ImmutableMap<String, Object> decodeJSONBytes(byte[] bytes)\n    {\n        // note: There is a Jackson module (datatype-guava) for directly reading into ImmutableMap,\n        // but would require adding dependency to that\n        try\n        {\n            return ImmutableMap.copyOf(JsonUtils.fromJsonMap(bytes));\n        }\n        catch (MarshalException e)\n        {\n            // Couple of options here: up to 4.0 simply returned null and caller failed with NPE.\n            // Seems cleaner to throw an exception\n            throw new MarshalException(\"Corrupt HintsDescriptor serialization, problem: \" + e.getMessage(), e);\n        }\n    }\n\n    private static void updateChecksumLong(CRC32 crc, long value)\n    {\n        updateChecksumInt(crc, (int) (value & 0xFFFFFFFFL));\n        updateChecksumInt(crc, (int) (value >>> 32));\n    }\n\n    private static void validateCRC(int expected, int actual) throws IOException\n    {\n        if (expected != actual)\n            throw new ChecksumMismatchException(\"Hints Descriptor CRC Mismatch\");\n    }\n}\n","sourceCodeStart":462,"sourceCodeEnd":496,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/hints/HintsDescriptor.java#L462-L496","documentation":"HintsDescriptor.decodeJSONBytes() throws MarshalException(\"Corrupt HintsDescriptor serialization, problem: ...\") when the descriptor's parameters blob fails to parse as a JSON map (JsonUtils.fromJsonMap throws, e.g. on MarshalException from invalid types/values). This wraps the underlying parse failure so callers of HintsDescriptor.deserialize get a clear error instead of a null/NPE.","triggerScenarios":"Reading a hints file whose descriptor bytes were corrupted (truncated header, bit rot, torn write), or whose parameters JSON was written by an incompatible format/version. Reached via HintsDescriptor.deserialize while opening the hints file.","commonSituations":"Hints files damaged by hard reboot/power loss; hand-edited or copied hints files; version skew where a newer/older writer produced parameter JSON the reader rejects; disk corruption in the hints directory.","solutions":["Remove the corrupt hints file from the hints directory so the node skips it and continues.","Check filesystem/disk health if multiple hints files show this error.","Restore hints files from backup or accept data loss (hints are transient delivery aids; run repair to converge replicas).","Upgrade/downgrade to matching Cassandra versions so descriptor parameter formats are compatible."],"exampleFix":"// before\nHintsDescriptor descriptor = HintsDescriptor.deserialize(input); // MarshalException\n// after\ntry\n{\n    descriptor = HintsDescriptor.deserialize(input);\n}\ncatch (IOException | MarshalException e)\n{\n    logger.warn(\"Discarding corrupt hints file\", e);\n    Files.deleteIfExists(hintsFilePath);\n}","handlingStrategy":"try-catch","validationCode":"// quick sanity probe before full deserialize: file must start with a plausible descriptor\nif (Files.size(hintsFile) < HintsDescriptor.ENCODED_SIZE) throw new IOException(\"hints file too small\");","typeGuard":null,"tryCatchPattern":"try { descriptor = HintsDescriptor.deserialize(input); } catch (IOException | MarshalException e) { logger.warn(\"Unreadable hints descriptor, removing file\", e); Files.deleteIfExists(file); }","preventionTips":["Never copy or edit hints files while the node is running.","Use clean shutdowns/drains so descriptor bytes are fully flushed.","Keep Cassandra versions aligned in the cluster to avoid format skew.","Alert on hints deserialization errors — they indicate storage corruption."],"tags":["java","hints","serialization","corruption"],"backgroundTag":"json-unmarshal-failed","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}