{"record":{"id":"ab925211db1ea410","repo":"pinpoint-apm/pinpoint","slug":"absolute-start-end-time-is-only-supported-for-trac-ab9252","errorCode":null,"errorMessage":"absolute start/end time is only supported for TRACE_V3 span events","messagePattern":"absolute start/end time is only supported for TRACE_V3 span events","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventBo.java","lineNumber":135,"sourceCode":"            throw new IllegalArgumentException(\"TRACE_V3 span event requires absolute start/end time\");\n        }\n\n        this.startTime = DEFAULT_START_TIME;\n        this.endTime = DEFAULT_END_TIME;\n        this.startElapsed = startElapsedMillis;\n        this.endElapsed = endElapsedMillis;\n    }\n\n    /**\n     * Sets absolute span event time for TRACE_V3 data.\n     * startTime/endTime are epoch nanos. startElapsedMillis is retained as the compatibility\n     * offset from the parent span/chunk start; endElapsedMillis is derived from endTime-startTime.\n     */\n    public void setTraceTime(int version, long startTime, long endTime, int startElapsedMillis) {\n        setVersion((byte) version);\n\n        if (version != SpanVersion.TRACE_V3) {\n            throw new IllegalArgumentException(\"absolute start/end time is only supported for TRACE_V3 span events\");\n        }\n        if (endTime < startTime) {\n            throw new IllegalArgumentException(\"span event end time must be greater than or equal to start time\");\n        }\n\n        this.startTime = startTime;\n        this.endTime = endTime;\n        this.startElapsed = startElapsedMillis;\n        this.endElapsed = (int) TimeUnit.NANOSECONDS.toMillis(endTime - startTime);\n    }\n\n    public boolean hasStartTime() {\n        return Byte.toUnsignedInt(version) == SpanVersion.TRACE_V3 && startTime != DEFAULT_START_TIME;\n    }\n\n    public long getStartTimeNanos() {\n        if (!hasStartTime()) {\n            throw new IllegalStateException(\"span event start time is not set\");","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanEventBo.java#L117-L153","documentation":"This SpanEventBo.setTraceTime overload (startTime/endTime/startElapsedMillis) exists specifically for TRACE_V3, which encodes absolute epoch-nano start/end times. Passing any other version is rejected because older formats cannot represent absolute nanosecond timestamps.","triggerScenarios":"Calling setTraceTime(version, startTime, endTime, startElapsedMillis) with a version other than SpanVersion.TRACE_V3, typically from the readSpanEvent/bind decode path when the absolute-time constructor is applied to V2 or unknown-version data.","commonSituations":"Applying the V3 absolute-time setter to V2 rows during mixed-version batch reads; migration scripts converting old data but stamping the wrong version byte; tests constructing V2 events with the V3 API.","solutions":["Only call the absolute-time overload when version == SpanVersion.TRACE_V3; otherwise use the relative-elapsed overload","Fix the decoder branch in readSpanEvent so V2 rows take the elapsed-millis path","Correct the version byte on the data being decoded if it was mislabeled"],"exampleFix":"// before\nspanEventBo.setTraceTime(SpanVersion.TRACE_V2, startNanos, endNanos, elapsed);\n// after\nif (version == SpanVersion.TRACE_V3) {\n    spanEventBo.setTraceTime(version, startNanos, endNanos, elapsed);\n} else {\n    spanEventBo.setTraceTime(version, startElapsed, endElapsed);\n}","handlingStrategy":"validation","validationCode":"if (version == SpanVersion.TRACE_V3) {\n    spanEventBo.setTraceTime(version, startNanos, endNanos, startElapsedMillis);\n} else {\n    spanEventBo.setTraceTime(version, startElapsed, endElapsed);\n}","typeGuard":"boolean supportsAbsoluteTime(int version) {\n    return version == SpanVersion.TRACE_V3;\n}","tryCatchPattern":"try {\n    spanEventBo.setTraceTime(version, startNanos, endNanos, elapsed);\n} catch (IllegalArgumentException e) {\n    logger.warn(\"Absolute time setter used with version \" + version, e);\n}","preventionTips":["Only construct V3 events with start/end absolute nanos","Keep version byte assignment and time setter choice adjacent in code","Cover mixed-version data in deserialization tests"],"tags":["java","serialization","trace-versioning"],"backgroundTag":"incompatible-source-type","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}