pinpoint-apm/pinpoint · error · UnsupportedOperationException
UNSUPPORTED_OPERATION
Error message
UNSUPPORTED_OPERATION
What it means
DisableTrace is Pinpoint's no-op Trace used when sampling is disabled; nearly all of its methods intentionally throw UnsupportedOperationException to signal that tracing operations are meaningless without an active sampled trace. getTraceId() is one of those stubs: a disabled trace has no trace context, so asking for its TraceId is unsupported. If you see this, code is interacting with a trace object that was never meant to carry real span data.
Source
Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DisableTrace.java:116
}
@Override
public void traceBlockEnd(int stackId) {
pop();
}
private int push() {
return this.depth++;
}
private void pop() {
this.depth--;
}
@Override
public TraceId getTraceId() {
throw new UnsupportedOperationException(UNSUPPORTED_OPERATION);
}
@Override
public boolean canSampled() {
// always return false
return false;
}
@Override
public boolean isRoot() {
return false;
}
@Override
public boolean isAsync() {
return false;
}
View on GitHub (pinned to 744c3d3075)
Solutions
- Check trace.canSampled() before calling getTraceId(); treat a disabled trace as having no trace ID.
- Wrap trace access in a null-object/facade that returns a placeholder TraceId (or skips logging) when sampling is off.
- Fix sampling configuration (profiler.sampling.type / sampling.rate) if traces were expected to be sampled.
- In plugin code, branch on whether the Trace is DisableTrace / isSampled and use the async or no-op variant appropriate for the interceptor.
- Upgrade Pinpoint if a bundled plugin is calling getTraceId on disabled traces — newer versions guard against this.
Example fix
// before
String id = trace.getTraceId().getTransactionIdAsString();
// after
if (trace.canSampled()) {
String id = trace.getTraceId().getTransactionIdAsString();
} else {
String id = null; // trace is disabled, no TraceId exists
} Defensive patterns
Strategy: validation
Validate before calling
if (trace != null && trace.canSampled()) {
TraceId traceId = trace.getTraceId(); // safe
} else {
// trace is disabled; skip trace-id usage
} Type guard
boolean isUsableTrace(com.navercorp.pinpoint.bootstrap.context.Trace t) {
return t != null && t.canSampled();
} Try / catch
try {
TraceId id = trace.getTraceId();
} catch (UnsupportedOperationException e) {
logger.debug("Trace is disabled, no TraceId available", e);
} Prevention
- Always call canSampled() before any trace read operation
- Treat DisableTrace as a null object: never persist or log from it
- In plugins, branch on isSampled and use async/no-op trace variants
- Test instrumentation with sampling disabled (rate=0) to catch these paths
- Check sampling config when trace IDs are expected but absent
When it happens
Trigger: Calling getTraceId() on a Trace obtained when canSampled() is false — i.e. the sampler decided not to sample the request (sampling rate 0, rate-limit sampling, or DisableTraceFactory produced the trace), and application or plugin code still calls trace.getTraceId().
Common situations: Applications that pass a Trace into custom interceptor/plugin code assuming it is always a real trace; sampling-rate misconfiguration making all traces disabled while instrumentation still queries trace IDs; tests injecting DisableTrace and exercising code paths that read the TraceId.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- startTime not recorded
- slot type:${slot}
- Failed to detect pinpoint profile. Please add -Dpinpoint.act
- unsupported profile or profile alias:
- UNSUPPORTED_OPERATION
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/0462de1accf76278.
Report an issue: GitHub.