pinpoint-apm/pinpoint · error · IllegalArgumentException

TRACE_V3 span requires absolute start/end time

Error message

TRACE_V3 span requires absolute start/end time

What it means

SpanBo.setTraceTime(int version, long startTime, int elapsedMillis) is only valid for pre-V3 spans, where time is stored as epoch-millis startTime plus elapsed duration. Calling it with version == SpanVersion.TRACE_V3 throws IllegalArgumentException because V3 spans require absolute start/end times via the other overload.

Solutions

  1. Call the 4-arg overload setTraceTime(version, startTime, endTime, elapsedMillis) for TRACE_V3 spans
  2. Check SpanVersion of the data before choosing which setTraceTime overload to use
  3. Fix readSpanValue/bind logic to branch on version and use the correct time representation
  4. Update tests/tests helpers like newMinimalSpan to build V3 spans with absolute times

Example fix

// before
span.setTraceTime(SpanVersion.TRACE_V3, startTime, elapsedMillis); // throws
// after
if (version == SpanVersion.TRACE_V3) {
    span.setTraceTime(version, startTime, endTime, elapsedMillis);
} else {
    span.setTraceTime(version, startTime, elapsedMillis);
}
Defensive patterns

Strategy: validation

Validate before calling

if (version == SpanVersion.TRACE_V3) { span.setTraceTime(version, startTime, endTime, elapsedMillis); } else { span.setTraceTime(version, startTime, elapsedMillis); }

Type guard

boolean isElapsedOnlySpan(int version) { return version != SpanVersion.TRACE_V3; }

Try / catch

try { span.setTraceTime(version, startTime, elapsedMillis); } catch (IllegalArgumentException e) { log.warn("wrong setTraceTime overload for version {}: {}", version, e.getMessage()); }

Prevention

When it happens

Trigger: Calling the elapsed-only setTraceTime overload (or bind/readSpanValue doing so) on span data whose version is TRACE_V3, e.g. after a data-format migration or with a hard-coded version constant.

Common situations: Migrating old collector code to V3 spans without switching to the absolute-time overload; tests constructing V3 spans with the legacy API; reading V3 rows with legacy bind logic.

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


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/027607ebe4bb53ff. Report an issue: GitHub.

Appendix: source

Thrown at commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanBo.java:186

        return TraceTimeAccessor.ofVersion(this.version);
    }

    public long getStartTimeMillis() {
        return timeAccessor().toMillis(startTime);
    }

    public long getStartTimeNanos() {
        return timeAccessor().toNanos(startTime);
    }

    /**
     * Sets elapsed-only span time for pre-V3 data.
     * startTime is epoch millis and endTime stays unset because the persisted model stores
     * startTime + elapsedMillis.
     */
    public void setTraceTime(int version, long startTime, int elapsedMillis) {
        if (version == SpanVersion.TRACE_V3) {
            throw new IllegalArgumentException("TRACE_V3 span requires absolute start/end time");
        }

        setVersion(version);
        this.startTime = startTime;
        this.elapsed = elapsedMillis;
        this.endTime = DEFAULT_END_TIME;
    }

    /**
     * Sets absolute span time for TRACE_V3 data.
     * startTime/endTime are epoch nanos. elapsedMillis is retained as the compatibility duration.
     */
    public void setTraceTime(int version, long startTime, long endTime, int elapsedMillis) {
        if (version != SpanVersion.TRACE_V3) {
            throw new IllegalArgumentException("absolute start/end time is only supported for TRACE_V3 spans");
        }
        if (endTime == DEFAULT_END_TIME) {
            throw new IllegalArgumentException("TRACE_V3 span end time is required");

View on GitHub (pinned to 744c3d3075)