quarkusio/quarkus · error · IllegalArgumentException
The Vert.x Context to attach the OpenTelemetry Context must
Error message
The Vert.x Context to attach the OpenTelemetry Context must be a duplicated Context
What it means
QuarkusContextStorage (the OpenTelemetry Context storage backed by Vert.x) only permits attaching an OpenTelemetry Context to a Vert.x Context that is a duplicated context (a child context forked per-request/operation). Attaching to a root/unduplicated context would leak traces across requests, so the storage throws IllegalArgumentException('The Vert.x Context to attach the OpenTelemetry Context must be a duplicated Context').
Source
Thrown at extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/QuarkusContextStorage.java:60
return vertxContext != null && isDuplicatedContext(vertxContext) ? attach(vertxContext, otelToAttach)
: FALLBACK_CONTEXT_STORAGE.attach(otelToAttach);
}
/**
* Attach the OpenTelemetry Context in the Vert.x Context if it is a duplicated Vert.x Context.
*
* @param vertxContext the Vert.x Context to attach the OpenTelemetry Context
* @param otelToAttach the OpenTelemetry Context to attach
* @return the Scope of the OpenTelemetry Context
*/
public Scope attach(io.vertx.core.Context vertxContext, Context otelToAttach) {
if (vertxContext == null || otelToAttach == null) {
return Scope.noop();
}
// We don't allow to attach the OpenTelemetry Context to a Vert.x Context that is not a duplicate.
if (!isDuplicatedContext(vertxContext)) {
throw new IllegalArgumentException(
"The Vert.x Context to attach the OpenTelemetry Context must be a duplicated Context");
}
Context otelBeforeAttach = getOtelContext(vertxContext);
if (otelToAttach == otelBeforeAttach) {
return Scope.noop();
}
if (log.isDebugEnabled()) {
log.debugv("Setting Otel context: {0}", OpenTelemetryUtil.getSpanData(otelToAttach));
}
VertxContext.localContextData(vertxContext).put(OTEL_CONTEXT, otelToAttach);
OpenTelemetryUtil.setMDCData(otelToAttach, vertxContext);
return new Scope() {
@OverrideView on GitHub (pinned to e1c734241f)
Solutions
- Ensure the Vert.x context is duplicated before attaching: call context.duplicate() and attach to the duplicated instance
- Only attach OTel contexts inside request-scoped/duplicated Vert.x contexts (e.g. within a route handler), not on root contexts
- Wrap work in vertx.executeBlocking or route handlers that Quarkus has already duplicated the context for
- Refactor custom instrumentation to use Context.root().with(...) capture inside the duplicated scope rather than attaching globally
Example fix
// before Context vertxCtx = vertx.getOrCreateContext(); Scope scope = contextStorage.attach(vertxCtx, otelCtx); // after Context vertxCtx = vertx.getOrCreateContext().duplicate(); Scope scope = contextStorage.attach(vertxCtx, otelCtx);
Defensive patterns
Strategy: type-guard
Validate before calling
// check before attaching
static boolean safeToAttach(Context vertxContext) {
return vertxContext != null
&& vertxContext.getLocal("__quarkus_otel_duplicated", false);
// or use OrderedMarkers/duplication marker via
// VertxContext.isDuplicatedContext(vertxContext) equivalent
} Type guard
static boolean isDuplicatedContext(Context ctx) {
// mirrors QuarkusContextStorage's own check: duplicated contexts carry
// the duplication marker local
return ctx != null
&& ctx.getLocal("__vertx.duplicated", false);
} Try / catch
try {
scope = contextStorage.attach(vertxContext, otelContext);
} catch (IllegalArgumentException e) {
if (e.getMessage() != null && e.getMessage().contains("duplicated Context")) {
vertxContext = vertxContext.duplicate();
scope = contextStorage.attach(vertxContext, otelContext);
} else {
throw e;
}
} Prevention
- Only attach OTel contexts inside route handlers or scopes Quarkus already duplicated
- Call context.duplicate() before attaching to a context you obtained yourself
- Never attach to vertx.getOrCreateContext() on startup/background threads
- Prefer running custom spans inside Vert.x timers/handlers rather than raw threads
When it happens
Trigger: Calling QuarkusContextStorage.attach(vertxContext, otelContext) with a Vert.x Context obtained outside a duplicated scope — e.g. Context from vertx.getOrCreateContext() on an event loop, a root context, or manual Context duplication skipped — while instrumenting code with OpenTelemetry scope management.
Common situations: Custom instrumentation or third-party libraries calling Context.current().with(...) and storage.attach(...) on a non-duplicated Vert.x context; running blocking/worker code that grabbed the wrong context; misuse of Vertx.currentContext() in startup or background threads.
Related errors
- The Vert.x Context is not set
- The OpenTelemetry Context is not set
- OpenTelemetryContextUnwrapper was not found
- No current Vertx context found
- No current Vertx context found
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/9dce1d7e245919a1.
Report an issue: GitHub.