quarkusio/quarkus · error · IllegalArgumentException

At least one key element is required to create a composite c

Error message

At least one key element is required to create a composite cache key instance

What it means

CompositeCacheKey combines the @CacheKey-annotated method parameters into one key object. Constructing it with zero elements would produce a key that cannot be distinguished, so the constructor throws IllegalArgumentException immediately.

Source

Thrown at extensions/cache/runtime/src/main/java/io/quarkus/cache/CompositeCacheKey.java:22

/**
 * A composite cache key is used by the annotations caching API when a method annotated with {@link CacheResult} or
 * {@link CacheInvalidate} is invoked and when the cache key is composed of several of the method arguments (annotated with
 * {@link CacheKey} or not). This class can also be used with the programmatic caching API.
 */
public class CompositeCacheKey {

    private final Object[] keyElements;

    /**
     * Constructor.
     *
     * @param keyElements key elements
     * @throws IllegalArgumentException if no key elements are provided
     */
    public CompositeCacheKey(Object... keyElements) {
        if (keyElements.length == 0) {
            throw new IllegalArgumentException(
                    "At least one key element is required to create a composite cache key instance");
        }
        this.keyElements = keyElements;
    }

    @Override
    public int hashCode() {
        return Arrays.deepHashCode(keyElements);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (CompositeCacheKey.class.isInstance(obj)) {
            final CompositeCacheKey other = (CompositeCacheKey) obj;
            return Arrays.deepEquals(keyElements, other.keyElements);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure the cached method has at least one parameter annotated @CacheKey, or any parameter when defaults apply.
  2. Provide a custom CacheKeyGenerator whose generate(...) returns a non-empty composite (pass at least one element to the constructor).
  3. If the method genuinely has no key material, use a constant key: `new CompositeCacheKey("constant")`.

Example fix

// before
public class MyKeyGen implements CacheKeyGenerator {
    public Object generate(Method m, Object... params) {
        return new CompositeCacheKey(); // empty
    }
}

// after
public Object generate(Method m, Object... params) {
    return new CompositeCacheKey(params.length > 0 ? params : new Object[]{"default-key"});
}
Defensive patterns

Strategy: validation

Validate before calling

Object[] keyElements = collectKeyElements();
if (keyElements == null || keyElements.length == 0) {
    throw new IllegalArgumentException("CompositeCacheKey needs at least one element");
}
CacheKey key = new CompositeCacheKey(keyElements);

Try / catch

try {
    CacheKey key = new CompositeCacheKey(elements);
} catch (IllegalArgumentException e) {
    // fall back to a constant key
    key = new CompositeCacheKey("default");
}

Prevention

When it happens

Trigger: Calling `new CompositeCacheKey()` with no arguments; runtime path where a cached method has no @CacheKey parameters (or all key material was filtered out, e.g. Kotlin Continuation dropped) and the interceptor builds an empty key.

Common situations: Using @CacheResult/@CacheInvalidate on a method with zero parameters without a custom key generator; a custom KeyGenerator returning an empty varargs array into CompositeCacheKey.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/80f75505b41874a1. Report an issue: GitHub.