redis/jedis · error · IllegalArgumentException

file is not a file

Error message

%s file %s is not a file

What it means

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.

Solutions

  1. Point the option at the actual file (e.g. truststore.jks, ca.crt), not its parent directory.
  2. Check with file.isDirectory()/file.isFile() before building the client.
  3. If you have a directory of certs, select or concatenate the specific file needed.

Example fix

// before
SslOptions.builder().trustStore(new File("/etc/ssl/certs")).build(); // dir
// after
SslOptions.builder().trustStore(new File("/etc/ssl/certs/ca.crt")).build();
Defensive patterns

Strategy: validation

Validate before calling

File f = new File(path);
if (!f.isFile()) throw new IllegalStateException("expected a file, got: " + path);

Try / catch

try {
  SslOptions opts = SslOptions.builder().trustStore(f).build();
} catch (IllegalArgumentException e) {
  log.error("SSL file invalid: {}", e.getMessage());
}

Prevention

When it happens

Trigger: 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/")).

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08). Data as JSON: /api/errors/e6d4e3781530eeed. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/redis/clients/jedis/SslOptions.java:479

    }

    private static char[] getPassword(char[] chars) {
        return chars != null ? Arrays.copyOf(chars, chars.length) : null;
    }

    /**
     * Assert that {@code file} {@link File#exists() exists}.
     *
     * @param keyword file recognizer
     * @param file
     * @throws IllegalArgumentException if the file doesn't exist
     */
    public static void assertFile(String keyword, File file) {
        if (!file.exists()) {
            throw new IllegalArgumentException(String.format("%s file %s does not exist", keyword, file));
        }
        if (!file.isFile()) {
            throw new IllegalArgumentException(String.format("%s file %s is not a file", keyword, file));
        }
    }

    /**
     * Supplier for a {@link InputStream} representing a resource. The resulting {@link InputStream} must be closed by
     * the calling code.
     */
    @FunctionalInterface
    public interface Resource {

        /**
         * Create a {@link Resource} that obtains a {@link InputStream} from a {@link URL}.
         *
         * @param url the URL to obtain the {@link InputStream} from.
         * @return a {@link Resource} that opens a connection to the URL and obtains the {@link InputStream} for it.
         */
        static Resource from(URL url) {

View on GitHub (pinned to 6dac31d4c2)