{"record":{"id":"c33fa1811e3bc3d5","repo":"apache/cassandra","slug":"history-file-s-is-not-readable-n","errorCode":null,"errorMessage":"History file %s is not readable.%n","messagePattern":"History file (.+?) is not readable\\.%n","errorType":"console","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/tools/nodetool/History.java","lineNumber":94,"sourceCode":"    }\n\n    /**\n     * Nodetool is appending command to history file before it is executed so us checking on its\n     * existence and validating it is not technically necessary however nodetool is also swallowing\n     * all errors when it was not succesful in appending to the history file so better to check here in that case.\n     *\n     * @param historyFile file to check that it is actually a file which exists and it is readable\n     */\n    void validateHistoryFile(File historyFile)\n    {\n        if (!historyFile.exists())\n            throw new IllegalStateException(String.format(\"History file %s does not exist.%n\", historyFile.absolutePath()));\n\n        if (!historyFile.isFile())\n            throw new IllegalStateException(String.format(\"History file %s is not a file.%n\", historyFile.absolutePath()));\n\n        if (!historyFile.isReadable())\n            throw new IllegalStateException(String.format(\"History file %s is not readable.%n\", historyFile.absolutePath()));\n    }\n}\n","sourceCodeStart":76,"sourceCodeEnd":97,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/tools/nodetool/History.java#L76-L97","documentation":"History.validateHistoryFile's final check confirms the file is readable by the current user; otherwise it throws IllegalStateException('History file <path> is not readable.'). This blocks the history command from opening the file for reading.","triggerScenarios":"Running nodetool as a different user than the one who created ~/.cassandra/nodetool.history (e.g. via sudo), or permissions were tightened to 0600 owned by another account.","commonSituations":"Using sudo without -E/-H so HOME changes; multi-user nodes where each operator runs nodetool but the history file was created by root; backup tools resetting permissions.","solutions":["Fix ownership/permissions: `sudo chown $(whoami) ~/.cassandra/nodetool.history && chmod 600 ~/.cassandra/nodetool.history`","Run nodetool as the user who owns the history file","Use `sudo -u <owner> nodetool history` to run under the file's owner"],"exampleFix":"// before\nsudo nodetool history   # runs as root, reads root's unreadable history\n// after\nsudo chown cassandra:cassandra ~/.cassandra/nodetool.history && nodetool history","handlingStrategy":"validation","validationCode":"# check readability and ownership before invoking\nHIST=\"$HOME/.cassandra/nodetool.history\"\n[ -r \"$HIST\" ] || { echo \"history file not readable: $HIST\"; exit 1; }","typeGuard":null,"tryCatchPattern":"try { runNodetool(\"history\"); } catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"is not readable\")) { log(\"chmod/chown the history file or run as its owner\"); return; }\n    throw e;\n}","preventionTips":["Run nodetool as the same user that owns the history file","Avoid sudo without -u/-H when the file belongs to your account","Keep 0600 ownership-consistent permissions on ~/.cassandra files"],"tags":["nodetool","history","permissions","filesystem"],"backgroundTag":"file-read-failed","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"}