pinpoint-apm/pinpoint · error · IllegalArgumentException
span event end time must be greater than or equal to start…
Error message
span event end time must be greater than or equal to start time
What it means
When constructing a TRACE_V3 span event with absolute times, the library validates that endTime >= startTime before deriving endElapsed = endTime - startTime. A negative duration is semantically invalid for a span event, so it is rejected with this IllegalArgumentException.
Solutions
- Ensure the end timestamp is captured at or after the start timestamp in the instrumentation
- Validate startTime <= endTime before calling setTraceTime and clamp or log invalid durations
- Check for mixing of different nanoTime/epoch bases when producing the two timestamps
Example fix
// before spanEventBo.setTraceTime(version, startNanos, endNanos, elapsed); // endNanos may be < startNanos // after long end = Math.max(endNanos, startNanos); spanEventBo.setTraceTime(version, startNanos, end, (int) TimeUnit.NANOSECONDS.toMillis(end - startNanos));
Defensive patterns
Strategy: validation
Validate before calling
if (endNanos < startNanos) {
endNanos = startNanos; // clamp zero-duration
}
spanEventBo.setTraceTime(version, startNanos, endNanos, elapsed); Type guard
boolean isValidDuration(long startNanos, long endNanos) {
return endNanos >= startNanos;
} Try / catch
try {
spanEventBo.setTraceTime(version, startNanos, endNanos, elapsed);
} catch (IllegalArgumentException e) {
logger.warn("Negative span duration start=" + startNanos + " end=" + endNanos, e);
} Prevention
- Capture the end timestamp strictly after the start timestamp
- Never mix timestamp sources (nanoTime vs epoch, different origins)
- Clamp or log non-positive durations at the instrumentation layer
When it happens
Trigger: Calling setTraceTime(version, startTime, endTime, startElapsedMillis) with endTime < startTime, e.g. from readSpanEvent/bind on rows whose encoded end nanos precede the start nanos, or from code computing timestamps out of order.
Common situations: Clock skew or timestamp source mixing (e.g. different System.nanoTime origins) when building V3 events; corrupted serialized nanos; buggy instrumentation that records the end timestamp before the start.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- annotationKey name must not be empty
- Either tagGroupList or fieldNameList must have a size of…
- eventIdentifier cannot be less than 0
- invalid operator - not found left operand. operator=
- invalid operator - not found right operand. operator=
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/3d3db239a422de7b.
Report an issue: GitHub.
Appendix: source
Thrown at commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventBo.java:138
this.startTime = DEFAULT_START_TIME;
this.endTime = DEFAULT_END_TIME;
this.startElapsed = startElapsedMillis;
this.endElapsed = endElapsedMillis;
}
/**
* Sets absolute span event time for TRACE_V3 data.
* startTime/endTime are epoch nanos. startElapsedMillis is retained as the compatibility
* offset from the parent span/chunk start; endElapsedMillis is derived from endTime-startTime.
*/
public void setTraceTime(int version, long startTime, long endTime, int startElapsedMillis) {
setVersion((byte) version);
if (version != SpanVersion.TRACE_V3) {
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;
}View on GitHub (pinned to 744c3d3075)