{"record":{"id":"e6d4e3781530eeed","repo":"redis/jedis","slug":"s-file-s-is-not-a-file","errorCode":null,"errorMessage":"%s file %s is not a file","messagePattern":"(.+?) file (.+?) is not a file","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/SslOptions.java","lineNumber":479,"sourceCode":"    }\n\n    private static char[] getPassword(char[] chars) {\n        return chars != null ? Arrays.copyOf(chars, chars.length) : null;\n    }\n\n    /**\n     * Assert that {@code file} {@link File#exists() exists}.\n     *\n     * @param keyword file recognizer\n     * @param file\n     * @throws IllegalArgumentException if the file doesn't exist\n     */\n    public static void assertFile(String keyword, File file) {\n        if (!file.exists()) {\n            throw new IllegalArgumentException(String.format(\"%s file %s does not exist\", keyword, file));\n        }\n        if (!file.isFile()) {\n            throw new IllegalArgumentException(String.format(\"%s file %s is not a file\", keyword, file));\n        }\n    }\n\n    /**\n     * Supplier for a {@link InputStream} representing a resource. The resulting {@link InputStream} must be closed by\n     * the calling code.\n     */\n    @FunctionalInterface\n    public interface Resource {\n\n        /**\n         * Create a {@link Resource} that obtains a {@link InputStream} from a {@link URL}.\n         *\n         * @param url the URL to obtain the {@link InputStream} from.\n         * @return a {@link Resource} that opens a connection to the URL and obtains the {@link InputStream} for it.\n         */\n        static Resource from(URL url) {\n","sourceCodeStart":461,"sourceCodeEnd":497,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/SslOptions.java#L461-L497","documentation":"Generic validation in SslOptions' assertFile helper: after confirming the path exists, it checks File#isFile() and throws when the path is a directory (or other non-regular file) where the named SSL artifact — e.g. a certificate or key file identified by the keyword — is expected.","triggerScenarios":"Passing a directory path (or symlink to a directory) where a truststore/keystore/cert file is expected, e.g. SslOptions.builder().trustStore(new File(\"/etc/ssl/\")).","commonSituations":"Pointing at a directory of certs instead of a single file; env var (e.g. SSL_CERT_DIR style) fed into a file-expecting API; trailing path mistakes.","solutions":["Point the option at the actual file (e.g. truststore.jks, ca.crt), not its parent directory.","Check with file.isDirectory()/file.isFile() before building the client.","If you have a directory of certs, select or concatenate the specific file needed."],"exampleFix":"// before\nSslOptions.builder().trustStore(new File(\"/etc/ssl/certs\")).build(); // dir\n// after\nSslOptions.builder().trustStore(new File(\"/etc/ssl/certs/ca.crt\")).build();","handlingStrategy":"validation","validationCode":"File f = new File(path);\nif (!f.isFile()) throw new IllegalStateException(\"expected a file, got: \" + path);","typeGuard":null,"tryCatchPattern":"try {\n  SslOptions opts = SslOptions.builder().trustStore(f).build();\n} catch (IllegalArgumentException e) {\n  log.error(\"SSL file invalid: {}\", e.getMessage());\n}","preventionTips":["Point options at files, not directories","Resolve env vars that may name directories (e.g. SSL_CERT_DIR)","Check f.isFile() before configuring"],"tags":["ssl","file","configuration","jedis"],"backgroundTag":"invalid-argument-value","analyzedSha":"6dac31d4c224fb3257c216f3985340c6f500cdcb","analyzedAt":"2026-09-08T04:55:01.204Z","contentChangedAt":"2026-09-08T04:55:01.204Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}