{"record":{"id":"da8a525a41eb1cfe","repo":"apache/cassandra","slug":"unexpected-eof-replaying-hints-likely-due-to","errorCode":null,"errorMessage":"Unexpected EOF replaying hints ({}), likely due to unflushed hint file on shutdown; continuing","messagePattern":"Unexpected EOF replaying hints \\((.+?)\\), likely due to unflushed hint file on shutdown; continuing","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/java/org/apache/cassandra/hints/HintsReader.java","lineNumber":198,"sourceCode":"            Hint hint;\n\n            do\n            {\n                InputPosition position = input.getSeekPosition();\n\n                if (input.isEOF())\n                    return endOfData(); // reached EOF\n\n                if (position.subtract(offset) >= PAGE_SIZE)\n                    return endOfData(); // read page size or more bytes\n\n                try\n                {\n                    hint = computeNextInternal();\n                }\n                catch (EOFException e)\n                {\n                    logger.warn(\"Unexpected EOF replaying hints ({}), likely due to unflushed hint file on shutdown; continuing\", descriptor.fileName(), e);\n                    return endOfData();\n                }\n                catch (IOException e)\n                {\n                    throw new FSReadError(e, file);\n                }\n            }\n            while (hint == null);\n\n            return hint;\n        }\n\n        private Hint computeNextInternal() throws IOException\n        {\n            input.resetCrc();\n            input.resetLimit();\n\n            int size = input.readInt();","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/hints/HintsReader.java#L180-L216","documentation":"While iterating a hints file, the reader hit an EOFException in the middle of computing the next hint. Cassandra treats a truncated tail as expected when a node was shut down before flushing the hints file completely, so it logs this warning, stops replay of that file, and continues rather than throwing. Data loss is limited to the unflushed tail.","triggerScenarios":"computeNext → computeNextInternal raises EOFException because the file ends mid-record — unflushed hint file from an abrupt shutdown, or a truncated file.","commonSituations":"kill -9 / crash / power loss with hints not yet flushed; storage-level truncation; reading a hints file copied mid-write.","solutions":["No action needed if shutdown was abrupt — this is the designed recovery path","If it happens on files that should be complete, check for disk/storage errors and verify file sizes vs. descriptor","Reduce risk by using graceful shutdown (nodetool drain / stop) so files are flushed"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// verify hints file tail before replaying (basic sanity)\nlong fileSize = Files.size(path);\nif (fileSize < HintsDescriptor.ENCODED_SIZE)\n  throw new IOException(\"hints file too small: \" + path);","typeGuard":null,"tryCatchPattern":"try {\n  hint = computeNextInternal();\n} catch (EOFException e) {\n  logger.warn(\"Truncated hints file {}, stopping replay\", descriptor.fileName());\n  return endOfData(); // accept partial replay\n}","preventionTips":["Shut down nodes gracefully so hint files are flushed","Investigate repeated EOF warnings — could be storage-level truncation","Back up hints directory only when the node is stopped"],"tags":["hints","replay","eof","truncation"],"backgroundTag":"unexpected-eof","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}