pinpoint-apm/pinpoint · warning
Already closed
Error message
Already closed {} What it means
DefaultTrace.close() logs 'Already closed {}' when close() is called on a trace whose `closed` flag is already set. Close finalizes the span (afterTime, flushing remaining call stack); the guard prevents double-finalization. The warning indicates duplicate lifecycle termination of the same Trace.
Solutions
- Call close() exactly once per Trace; move cleanup into a single owner (e.g. one finally block)
- Add an idempotency guard in your code before closing
- Audit async code paths so only the thread that completes the request closes the trace
- Check agent version/release notes for duplicate-close fixes in trace lifecycle handling
Example fix
// before
finally {
trace.close();
}
// ... elsewhere
trace.close(); // warns Already closed
// after
if (!trace.isClosed()) { // if API available, or track locally
trace.close();
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!trace.isClosed()) { trace.close(); } Type guard
boolean needsClose(Trace t) { return t != null && !t.isClosed(); } Try / catch
try { trace.close(); } catch (RuntimeException e) { logger.debug("already closed", e); } Prevention
- Close each Trace exactly once, from a single owner
- Avoid defensive duplicate close() calls in nested layers
- For async flows, close on the thread that completes the request
- Track closed state locally when the API lacks isClosed()
When it happens
Trigger: Invoking close() twice on the same DefaultTrace, e.g. from both an application cleanup path and the agent's trace finalizer, or from a finally block plus a framework shutdown hook.
Common situations: Request-scoped cleanup code that closes traces defensively; async request handling where both the worker thread and continuation close the trace; misconfigured async trace factories reusing references.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Already closed
- beforeTrace
- Corrupted call stack found TraceRoot
- 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/40d45b168cd69a2c.
Report an issue: GitHub.
Appendix: source
Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/DefaultTrace.java:183
if (spanEvent.isTimeRecording()) {
spanEvent.markAfterTime();
}
logSpan(spanEvent);
// state restore
final SpanEvent previous = callStack.peek();
wrappedSpanEventRecorder(wrappedSpanEventRecorder, previous);
}
@Override
public boolean isClosed() {
return closed;
}
@Override
public void close() {
if (closed) {
logger.warn("Already closed {}", this);
return;
}
closed = true;
final long afterTime = System.currentTimeMillis();
if (!callStack.empty()) {
if (logger.isWarnEnabled()) {
stackDump("not empty call stack");
}
// skip
} else {
if (span.isTimeRecording()) {
span.markAfterTime(afterTime);
}
logSpan();
}
this.wrappedSpanEventRecorder.close();View on GitHub (pinned to 744c3d3075)