testcontainers/testcontainers-java · error · IllegalArgumentException

Kibana encryption key must be at least 32 characters long

Error message

Kibana encryption key must be at least 32 characters long

What it means

KibanaContainer.withEncryptionKey(String) validates that the provided Kibana encryption key is non-null and at least 32 characters long, because Kibana requires xpack.encryptedSavedObjects.encryptionKey keys of adequate length. Keys shorter than 32 characters would cause Kibana to fail at startup, so the library rejects them eagerly with IllegalArgumentException.

Solutions

  1. Provide a key of at least 32 characters, e.g. a 64-char hex string.
  2. Generate one with a random generator (e.g. openssl rand -hex 32) and share it across tests that need stable encrypted saved objects.
  3. Omit withEncryptionKey if you don't need encrypted saved objects and the library default suffices.

Example fix

// before
.withEncryptionKey("short-key")
// after
.withEncryptionKey("6f4c2a9d8b1e7f3a5c0d9e8b7a6f5e4d3c2b1a0987654321abcdef0123456789")
Defensive patterns

Strategy: validation

Validate before calling

if (key == null || key.length() < 32) throw new IllegalArgumentException("Kibana encryption key must be at least 32 chars");

Prevention

When it happens

Trigger: Calling withEncryptionKey with null or with any string shorter than 32 characters.

Common situations: Hardcoding short placeholder keys in tests; truncating a generated key; copying an example key from documentation that is shorter than required.

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 testcontainers/testcontainers-java@8e549514e3 (2026-09-12). Data as JSON: /api/errors/5f511c384f3c3a15. Report an issue: GitHub.

Appendix: source

Thrown at modules/elasticsearch/src/main/java/org/testcontainers/elasticsearch/KibanaContainer.java:129

        dockerImageName.assertCompatibleWith(DEFAULT_IMAGE_NAME);
        this.encryptionKey = stableConfigKey(dockerImageName);

        withExposedPorts(KIBANA_DEFAULT_PORT);
        //we have to explicitly set wait the strategy later on in configure, once we know the security configuration
        setWaitStrategy(null);
    }

    /**
     * Sets the encryption key used for Kibana's encrypted saved objects.
     * The key must be at least 32 characters. When not set, a deterministic default derived from
     * the image name is used, which is required for {@link #withReuse(boolean)} to work correctly.
     *
     * @param encryptionKey the encryption key
     * @return this container instance
     */
    public KibanaContainer withEncryptionKey(String encryptionKey) {
        if (encryptionKey == null || encryptionKey.length() < 32) {
            throw new IllegalArgumentException("Kibana encryption key must be at least 32 characters long");
        }
        this.encryptionKey = encryptionKey;
        return this;
    }

    /**
     * Enables or disables container reuse across JVM runs.
     *
     * <p><b>Supported in external mode only.</b> When Kibana is configured via
     * {@link #withElasticsearchUrl(String)}, the container configuration is fully deterministic
     * and TC can reliably locate the running container on subsequent runs.
     *
     * <p>Reuse is <b>not supported in managed mode</b> (i.e. when this container was created with
     * an {@link ElasticsearchContainer}). Managed mode introduces several non-deterministic inputs
     * into the container hash on every run (ad-hoc network ID, random network alias, fresh service
     * account token), so TC always sees a different hash and starts a fresh container instead of
     * reusing the existing one. This is a framework-level characteristic that affects any container
     * connected via {@code withNetwork()} — not specific to {@code KibanaContainer}.

View on GitHub (pinned to 8e549514e3)