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

  1. Call hasStartTime() before getStartTimeNanos() and fall back to computed time (parent start + startElapsed) when false
  2. Ensure TRACE_V3 events are always built via the absolute-time setTraceTime overload
  3. 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

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


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)