pinpoint-apm/pinpoint · error · PinpointException
Corrupted call stack found TraceRoot
Error message
Corrupted call stack found TraceRoot:{}, CallStack:{} What it means
DefaultTrace.stackDump(String) logs 'Corrupted call stack found TraceRoot:{}, CallStack:{}' and attaches a PinpointException when the internal CallStack is inconsistent — typically a traceBlockEnd() with no matching traceBlockBegin(), or leftover unended span events. It dumps the trace root and full call stack for diagnosis; the exception is only for logging, not always rethrown.
Solutions
- Verify every traceBlockBegin() has a matching traceBlockEnd() in the same thread, including on exception paths (use try/finally)
- Check interceptor/plugin implementations for early returns that skip the end-side interceptor
- Enable the logged dump: inspect TraceRoot and CallStack contents to find the unbalanced block
- Upgrade the pinpoint agent if async trace handling versions have known stack-corruption fixes
Example fix
// before
trace.traceBlockBegin();
if (bad) return; // skips traceBlockEnd -> corrupted stack
trace.traceBlockEnd();
// after
trace.traceBlockBegin();
try {
if (bad) return;
} finally {
trace.traceBlockEnd();
} Defensive patterns
Strategy: validation
Validate before calling
// ensure begin/end are balanced before ending
if (spanBeginDepth <= 0) { throw new IllegalStateException("traceBlockEnd without begin"); } Try / catch
try { trace.traceBlockEnd(); } catch (PinpointException e) { logger.warn("unbalanced trace block", e); } Prevention
- Always pair traceBlockBegin/traceBlockEnd in try/finally
- Never call trace methods across threads on the same Trace
- Test instrumented code with exceptions and early returns
- Keep begin/end instrumentation in matched interceptor pairs
When it happens
Trigger: Calling traceBlockEnd() without a prior traceBlockBegin(); calling traceBlockBegin/traceBlockEnd from different threads on the same Trace; a begin/end pair skipped because an exception short-circuited the ending interceptor; trace close while span events remain unbalanced.
Common situations: Buggy interceptor/plugin code where the end interceptor is not invoked (early return, swallowed exception); asynchronous work continuing after the synchronous trace ended; agent bugs in async trace continuation.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Already closed
- Already closed
- beforeTrace
- TraceBlock already begin. trace=
- absolute start/end time is only supported for TRACE_V3 spans
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/01f167978b3507ca.
Report an issue: GitHub.
Appendix: source
Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTrace.java:125
return wrappedSpanEventRecorder(wrappedSpanEventRecorder, spanEvent);
}
private SpanEvent traceBlockBegin0(final int stackId) {
if (closed) {
if (logger.isWarnEnabled()) {
stackDump("already closed trace");
}
return dummySpanEvent();
}
// Set properties for the case when stackFrame is not used as part of Span.
final SpanEvent spanEvent = newSpanEvent(stackId);
this.callStack.push(spanEvent);
return spanEvent;
}
private void stackDump(String caused) {
PinpointException exception = new PinpointException(caused);
logger.warn("Corrupted call stack found TraceRoot:{}, CallStack:{}", getTraceRoot(), callStack, exception);
}
@Override
public void traceBlockEnd() {
traceBlockEnd(DEFAULT_STACKID);
}
@Override
public void traceBlockEnd(int stackId) {
if (closed) {
if (logger.isWarnEnabled()) {
stackDump("already closed trace");
}
return;
}
final SpanEvent spanEvent = callStack.pop();
if (spanEvent == null) {View on GitHub (pinned to 744c3d3075)