{"record":{"id":"2b279bd22b896f30","repo":"apache/cassandra","slug":"dictionary-file-s-is-not-readable","errorCode":null,"errorMessage":"Dictionary file %s is not readable.","messagePattern":"Dictionary file (.+?) is not readable\\.","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/guardrails/CassandraPasswordConfiguration.java","lineNumber":283,"sourceCode":"            minimumLenghtOfFailCharacteristics += minimumLengthsFail[i];\n\n        if (minimumLenghtOfFailCharacteristics > lengthFail)\n            throw new ConfigurationException(format(\"The shortest password to pass the failing validator for any %s \" +\n                                                    \"characteristics out of %s is %s but you have set the %s to %s.\",\n                                                    characteristicsFail,\n                                                    MAX_CHARACTERISTICS,\n                                                    minimumLenghtOfFailCharacteristics,\n                                                    LENGTH_FAIL_KEY,\n                                                    lengthFail));\n\n        if (dictionary != null)\n        {\n            File dictionaryFile = new File(dictionary);\n            if (!dictionaryFile.exists())\n                throw new ConfigurationException(format(\"Dictionary file %s does not exist.\", dictionary));\n\n            if (!dictionaryFile.isReadable())\n                throw new ConfigurationException(format(\"Dictionary file %s is not readable.\", dictionary));\n        }\n    }\n\n    private ConfigurationException getValidationException(String key1, int value1, String key2, int value2)\n    {\n        return new ConfigurationException(format(\"%s of value %s is less or equal to %s of value %s\",\n                                                 key1, value1,\n                                                 key2, value2));\n    }\n}\n","sourceCodeStart":265,"sourceCodeEnd":294,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/guardrails/CassandraPasswordConfiguration.java#L265-L294","documentation":"When a dictionary file is configured for the password guardrail, Cassandra checks not only that it exists but that the Cassandra process can read it. If File.isReadable() returns false, a ConfigurationException is thrown.","triggerScenarios":"Configuring cassandra.password_validator.dictionary to a file whose OS permissions deny read access to the user running the Cassandra process; a root-owned file with 0600 permissions; restrictive SELinux/AppArmor policies.","commonSituations":"Admin creates the dictionary as root with default umask; deployment tool deploys the file with wrong ownership; containerized Cassandra runs as a non-root user without access to a host-mounted file.","solutions":["Fix file permissions so the Cassandra process user can read it, e.g. `chown cassandra:cassandra <path> && chmod 640 <path>`","Check the OS user the Cassandra process runs as (ps aux | grep cassandra) and grant read access accordingly","Investigate SELinux/AppArmor denials (audit logs) if POSIX permissions look correct"],"exampleFix":"// before\n-rw------- root root /etc/cassandra/passwords.txt  (cassandra user cannot read)\n// after\nsudo chown cassandra:cassandra /etc/cassandra/passwords.txt && sudo chmod 640 /etc/cassandra/passwords.txt","handlingStrategy":"validation","validationCode":"import java.io.File;\nFile f = new File(dictionaryPath);\nif (f.exists() && !f.canRead()) throw new IllegalStateException(\"Not readable by this process: \" + dictionaryPath);","typeGuard":null,"tryCatchPattern":"try {\n    applyGuardrailConfig(config);\n} catch (ConfigurationException e) {\n    if (e.getMessage().contains(\"is not readable\")) {\n        logger.error(\"Fix OS permissions/ownership for the dictionary file: {}\", e.getMessage());\n    }\n}","preventionTips":["Set ownership to the Cassandra service user when deploying the file","chmod 640 (owner group readable) as the standard deployment mode","Check SELinux/AppArmor policies in hardened environments","Run a post-deploy readability check as the cassandra user (sudo -u cassandra cat <path>)"],"tags":["configuration","guardrails","filesystem","permissions"],"backgroundTag":"permission-denied","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"}