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

  1. Verify every traceBlockBegin() has a matching traceBlockEnd() in the same thread, including on exception paths (use try/finally)
  2. Check interceptor/plugin implementations for early returns that skip the end-side interceptor
  3. Enable the logged dump: inspect TraceRoot and CallStack contents to find the unbalanced block
  4. 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

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


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)