perwendel/spark · error · IllegalArgumentException

Must provide a keystore file to run secured

Error message

Must provide a keystore file to run secured

What it means

Service.secure(...) switches the embedded server to HTTPS. A keystore file holding the server certificate/key is mandatory for TLS; without it Spark cannot build its SslStores. Spark throws IllegalArgumentException when keystoreFile is null, before any route mapping exception check would even apply.

Solutions

  1. Pass a valid, existing keystore file path as the first argument to secure(), e.g. secure("certs/keystore.jks", "password", null, null, null).
  2. Load the keystore path from config and fail early with a clear message if it is missing before calling secure().
  3. Verify the config/env providing the keystore location is actually loaded at startup.

Example fix

// before
String keystore = System.getProperty("keystore"); // null
Spark.secure(keystore, "pass", null, null);
// after
String keystore = Objects.requireNonNull(System.getProperty("keystore"), "keystore path required");
Spark.secure(keystore, "pass", null, null);
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(keystoreFile, "Must provide a keystore file to run secured");
if (!java.nio.file.Files.exists(java.nio.file.Paths.get(keystoreFile))) {
    throw new IllegalArgumentException("Keystore not found: " + keystoreFile);
}
Spark.secure(keystoreFile, password, null, null);

Type guard

boolean isConfiguredSsl(String keystoreFile) { return keystoreFile != null && !keystoreFile.isEmpty(); }

Try / catch

try {
    Spark.secure(keystoreFile, password, null, null);
} catch (IllegalArgumentException e) {
    LOG.error("SSL misconfiguration: {}", e.getMessage());
    throw new IllegalStateException("Aborting startup: keystore missing", e);
}

Prevention

When it happens

Trigger: Calling secure(null, ...) — i.e. passing a null keystore path — or a variable holding the keystore location that was never populated (config not loaded, property missing, env var empty).

Common situations: Keystore path read from application.properties/yml that is missing; conditional config where only truststore was set; forgetting the keystore argument when upgrading from an older secure() overload.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of perwendel/spark@1973e402f5 (2026-09-10). Data as JSON: /api/errors/8b26c27becc180ee. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/spark/Service.java:293

     * @param truststoreFile     the truststore file location as string, leave null to reuse
     *                           keystore
     * @param needsClientCert    Whether to require client certificate to be supplied in
     *                           request
     * @param truststorePassword the trust store password
     * @return the object with connection set to be secure
     */
    public synchronized Service secure(String keystoreFile,
                                       String keystorePassword,
                                       String certAlias,
                                       String truststoreFile,
                                       String truststorePassword,
                                       boolean needsClientCert) {
        if (initialized) {
            throwBeforeRouteMappingException();
        }

        if (keystoreFile == null) {
            throw new IllegalArgumentException(
                    "Must provide a keystore file to run secured");
        }

        sslStores = SslStores.create(keystoreFile, keystorePassword, certAlias, truststoreFile, truststorePassword, needsClientCert);
        return this;
    }

    /**
     * Configures the embedded web server's thread pool.
     *
     * @param maxThreads max nbr of threads.
     * @return the object with the embedded web server's thread pool configured
     */
    public synchronized Service threadPool(int maxThreads) {
        return threadPool(maxThreads, -1, -1);
    }

    /**

View on GitHub (pinned to 1973e402f5)