quarkusio/quarkus · error · IllegalArgumentException
Metadata key already exists:
Error message
Metadata key already exists:
What it means
SignalContext.putMetadata refuses to overwrite an existing metadata key: if the key is already present in the signal's existing metadata map, the call throws IllegalArgumentException. Metadata is write-once, so callers must use unique keys per signal context.
Source
Thrown at extensions/signals/runtime/src/main/java/io/quarkus/signals/runtime/impl/SignalImpl.java:261
static class EnrichmentContextImpl implements SignalMetadataEnricher.EnrichmentContext {
private final SignalContext<?> signalContext;
private Map<String, Object> additions;
EnrichmentContextImpl(SignalContext<?> signalContext) {
this.signalContext = signalContext;
}
@Override
public SignalContext<?> signalContext() {
return signalContext;
}
@Override
public void putMetadata(String key, Object value) {
if (signalContext.metadata().containsKey(key)) {
throw new IllegalArgumentException("Metadata key already exists: " + key);
}
if (additions == null) {
additions = new HashMap<>();
}
if (additions.putIfAbsent(key, value) != null) {
throw new IllegalArgumentException("Metadata key already exists: " + key);
}
}
Map<String, Object> additions() {
return additions != null ? additions : Map.of();
}
}
class SignalContextImpl<SIGNAL> implements SignalContext<SIGNAL> {
private final SIGNAL signal;
private final Map<String, Object> meta;View on GitHub (pinned to e1c734241f)
Solutions
- Use a distinct, namespaced key (e.g. prefix with your application/module name)
- Check containsKey() or read the existing value first and skip the put when present
- If overwriting is intended, restructure to compose values instead of re-putting the same key
Example fix
// before
context.putMetadata("traceId", id);
// after
if (!context.metadata().containsKey("myapp.traceId")) {
context.putMetadata("myapp.traceId", id);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (context.metadata().containsKey(key)) return; // or compose with existing value
Type guard
boolean canPut(SignalContext ctx, String key) { return !ctx.metadata().containsKey(key); } Try / catch
try { ctx.putMetadata(key, value); }
catch (IllegalArgumentException e) { log.warnf("Metadata key %s already set: %s", key, e.getMessage()); } Prevention
- Namespace metadata keys with your application prefix
- Treat metadata as write-once; compute values once per context
- Check metadata() before adding in shared/interceptor code
When it happens
Trigger: Calling putMetadata(key, value) with a key that already exists in signalContext.metadata() — typically a hardcoded key set earlier in the pipeline or by another participant of the same signal.
Common situations: Two interceptors/filters writing the same metadata key (e.g. "traceId"); re-invoking processing logic on the same context; framework code reserving keys an application also tries to set.
Related errors
- Unable to determine groupId and artifactId of the jar that c
- Key already registered ${key}
- Only one handler can be configured with the same name '%s'
- Duplicate key %s (attempted merging values %s and %s)
- Failed to locate 'artifact' or 'group-id' and 'artifact-id'
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/66a205f5548a33a0.
Report an issue: GitHub.