{"record":{"id":"027607ebe4bb53ff","repo":"pinpoint-apm/pinpoint","slug":"trace-v3-span-requires-absolute-start-end-time","errorCode":null,"errorMessage":"TRACE_V3 span requires absolute start/end time","messagePattern":"TRACE_V3 span requires absolute start/end time","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanBo.java","lineNumber":186,"sourceCode":"        return TraceTimeAccessor.ofVersion(this.version);\n    }\n\n    public long getStartTimeMillis() {\n        return timeAccessor().toMillis(startTime);\n    }\n\n    public long getStartTimeNanos() {\n        return timeAccessor().toNanos(startTime);\n    }\n\n    /**\n     * Sets elapsed-only span time for pre-V3 data.\n     * startTime is epoch millis and endTime stays unset because the persisted model stores\n     * startTime + elapsedMillis.\n     */\n    public void setTraceTime(int version, long startTime, int elapsedMillis) {\n        if (version == SpanVersion.TRACE_V3) {\n            throw new IllegalArgumentException(\"TRACE_V3 span requires absolute start/end time\");\n        }\n\n        setVersion(version);\n        this.startTime = startTime;\n        this.elapsed = elapsedMillis;\n        this.endTime = DEFAULT_END_TIME;\n    }\n\n    /**\n     * Sets absolute span time for TRACE_V3 data.\n     * startTime/endTime are epoch nanos. elapsedMillis is retained as the compatibility duration.\n     */\n    public void setTraceTime(int version, long startTime, long endTime, int elapsedMillis) {\n        if (version != SpanVersion.TRACE_V3) {\n            throw new IllegalArgumentException(\"absolute start/end time is only supported for TRACE_V3 spans\");\n        }\n        if (endTime == DEFAULT_END_TIME) {\n            throw new IllegalArgumentException(\"TRACE_V3 span end time is required\");","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanBo.java#L168-L204","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Call the 4-arg overload setTraceTime(version, startTime, endTime, elapsedMillis) for TRACE_V3 spans","Check SpanVersion of the data before choosing which setTraceTime overload to use","Fix readSpanValue/bind logic to branch on version and use the correct time representation","Update tests/tests helpers like newMinimalSpan to build V3 spans with absolute times"],"exampleFix":"// before\nspan.setTraceTime(SpanVersion.TRACE_V3, startTime, elapsedMillis); // throws\n// after\nif (version == SpanVersion.TRACE_V3) {\n    span.setTraceTime(version, startTime, endTime, elapsedMillis);\n} else {\n    span.setTraceTime(version, startTime, elapsedMillis);\n}","handlingStrategy":"validation","validationCode":"if (version == SpanVersion.TRACE_V3) { span.setTraceTime(version, startTime, endTime, elapsedMillis); } else { span.setTraceTime(version, startTime, elapsedMillis); }","typeGuard":"boolean isElapsedOnlySpan(int version) { return version != SpanVersion.TRACE_V3; }","tryCatchPattern":"try { span.setTraceTime(version, startTime, elapsedMillis); } catch (IllegalArgumentException e) { log.warn(\"wrong setTraceTime overload for version {}: {}\", version, e.getMessage()); }","preventionTips":["Branch on SpanVersion before setting span times","Use the absolute-time overload for all V3 spans","Update span-building helpers/tests to the versioned API"],"tags":["java","span","api-misuse","versioning"],"backgroundTag":"invalid-argument-value","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}