pinpoint-apm/pinpoint · error · IllegalStateException
span event start time is not set
Error message
span event start time is not set
What it means
getStartTimeNanos returns the absolute start time in nanos, which only exists for TRACE_V3 span events whose startTime was explicitly set (not the DEFAULT_START_TIME sentinel). If either condition fails, the start time is not available and the method throws IllegalStateException instead of returning a meaningless value.
Solutions
- Call hasStartTime() before getStartTimeNanos() and fall back to computed time (parent start + startElapsed) when false
- Ensure TRACE_V3 events are always built via the absolute-time setTraceTime overload
- Check the event's trace version and route V2 events through the elapsed-millis code path
Example fix
// before
long start = spanEventBo.getStartTimeNanos();
// after
long start = spanEventBo.hasStartTime()
? spanEventBo.getStartTimeNanos()
: parentStartTime + TimeUnit.MILLISECONDS.toNanos(spanEventBo.getStartElapsed()); Defensive patterns
Strategy: type-guard
Validate before calling
long start = spanEventBo.hasStartTime()
? spanEventBo.getStartTimeNanos()
: fallbackStartTime(spanEventBo); Type guard
boolean canReadStartTime(SpanEventBo e) {
return e.hasStartTime();
} Try / catch
try {
return spanEventBo.getStartTimeNanos();
} catch (IllegalStateException e) {
return parentStartTime + TimeUnit.MILLISECONDS.toNanos(spanEventBo.getStartElapsed());
} Prevention
- Check hasStartTime()/hasEndTime() before reading absolute nanos
- Build V3 events via the absolute-time setTraceTime overload so fields are always populated
- Route non-V3 events through elapsed-millis logic instead
When it happens
Trigger: Calling getStartTimeNanos on a span event that is not TRACE_V3, or a V3 event built via the relative-elapsed overload where startTime was never set (still DEFAULT_START_TIME).
Common situations: Rendering/serialization code (e.g. startTime in the Web UI DTO mapper) running over V2 events; callers skipping the hasStartTime() check; partially initialized V3 events after the relative-time decode path.
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
- span event end time is not set
- absolute start/end time is only supported for TRACE_V3 span…
- IllegalStateException
- span chunk keyTime is only supported for TRACE_V2 or…
- startTime not recorded
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/7780aaf7a7d35e26.
Report an issue: GitHub.
Appendix: source
Thrown at commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventBo.java:153
throw new IllegalArgumentException("absolute start/end time is only supported for TRACE_V3 span events");
}
if (endTime < startTime) {
throw new IllegalArgumentException("span event end time must be greater than or equal to start time");
}
this.startTime = startTime;
this.endTime = endTime;
this.startElapsed = startElapsedMillis;
this.endElapsed = (int) TimeUnit.NANOSECONDS.toMillis(endTime - startTime);
}
public boolean hasStartTime() {
return Byte.toUnsignedInt(version) == SpanVersion.TRACE_V3 && startTime != DEFAULT_START_TIME;
}
public long getStartTimeNanos() {
if (!hasStartTime()) {
throw new IllegalStateException("span event start time is not set");
}
return startTime;
}
public boolean hasEndTime() {
return Byte.toUnsignedInt(version) == SpanVersion.TRACE_V3 && endTime != DEFAULT_END_TIME;
}
public long getEndTimeNanos() {
if (!hasEndTime()) {
throw new IllegalStateException("span event end time is not set");
}
return endTime;
}
public int getServiceType() {
return serviceType;
}View on GitHub (pinned to 744c3d3075)