quarkusio/quarkus · error · IllegalArgumentException

Not allowed to remove key '${KEY_INTERCEPTOR_BINDINGS}' from

Error message

Not allowed to remove key '${KEY_INTERCEPTOR_BINDINGS}' from the context data map

What it means

ContextDataMap.remove() refuses to remove ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS, the framework-managed entry holding the current interceptor bindings for the invocation. Removing it would break subsequent interceptor metadata lookups, so ArC throws IllegalArgumentException; removing any other key is allowed.

Source

Thrown at independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ContextDataMap.java:131

            set.addAll(delegate.keySet());
            set.add(ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS);
            return set;
        }
    }

    @Override
    public void putAll(Map<? extends String, ? extends Object> m) {
        if (m.containsKey(ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS)) {
            throw new IllegalArgumentException(
                    "Not allowed to put key '" + ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS + "' in the context data map");
        }
        getDelegateForWrite(m.size()).putAll(m);
    }

    @Override
    public Object remove(Object key) {
        if (ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS.equals(key)) {
            throw new IllegalArgumentException("Not allowed to remove key '" + ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS
                    + "' from the context data map");
        } else if (delegate == null) {
            return null;
        } else {
            return delegate.remove(key);
        }
    }

    @Override
    public int size() {
        return getDelegateForRead().size() + 1;
    }

    @Override
    public Collection<Object> values() {
        if (delegate == null) {
            return Set.of(interceptorBindings);
        } else {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Skip the reserved key in removal loops (compare against ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS).
  2. Remove only your own named keys instead of clearing everything.
  3. Store interceptor-related data under your own key if you need to manage it separately.

Example fix

// before
for (String key : contextData.keySet()) { contextData.remove(key); } // hits reserved key

// after
contextData.keySet().removeIf(k -> !ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS.equals(k));
Defensive patterns

Strategy: validation

Validate before calling

if (ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS.equals(key)) {
    throw new IllegalStateException("cannot remove reserved interceptor bindings key");
}
contextData.remove(key);

Type guard

static boolean isRemovableKey(Object key) {
    return !ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS.equals(key);
}

Try / catch

try {
    contextData.remove(key);
} catch (IllegalArgumentException e) {
    if (!e.getMessage().contains("Not allowed to remove key")) throw e;
    // skip reserved key
}

Prevention

When it happens

Trigger: Calling getContextData().remove(ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS) or a bulk cleanup loop that tries to remove every key, including the reserved one.

Common situations: Cleanup code iterating over contextData.keySet() and removing all entries after an invocation; code that copied a Weld pattern assuming the bindings key is user-deletable.

Related errors


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