{"record":{"id":"7d986e0d6c22a55d","repo":"pinpoint-apm/pinpoint","slug":"span-end-time-must-be-greater-than-or-equal-to-sta","errorCode":null,"errorMessage":"span end time must be greater than or equal to start time","messagePattern":"span end time must be greater than or equal to start time","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanBo.java","lineNumber":207,"sourceCode":"        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\");\n        }\n        if (endTime < startTime) {\n            throw new IllegalArgumentException(\"span end time must be greater than or equal to start time\");\n        }\n\n        setVersion(version);\n        this.startTime = startTime;\n        this.elapsed = elapsedMillis;\n        this.endTime = endTime;\n    }\n\n    public boolean hasEndTime() {\n        return endTime != DEFAULT_END_TIME;\n    }\n\n    public long getEndTimeMillis() {\n        if (hasEndTime()) {\n            return timeAccessor().toMillis(endTime);\n        }\n        return getStartTimeMillis() + elapsed;\n    }","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/commons-server/src/main/java/com/navercorp/pinpoint/common/server/bo/SpanBo.java#L189-L225","documentation":"V3 spans store absolute start and end times, so setTraceTime enforces the invariant endTime >= startTime and throws IllegalArgumentException on violation. A negative interval means corrupt, reordered, or unit-mismatched timestamps.","triggerScenarios":"Calling setTraceTime(version, startTime, endTime, elapsedMillis) with endTime < startTime — typically from mixing millis and nanos, clocks skew across hops, or truncated timestamp bytes.","commonSituations":"Unit confusion (epoch millis passed as nanos), timestamps sourced from different machines without clock sync, corrupted HBase values, or off-by-one byte reads.","solutions":["Verify both timestamps use the same unit (epoch nanos for V3) and fix conversions","Clamp or reject in the reader when endTime < startTime instead of letting it propagate","Check clock sources: use one clock or apply known skew corrections","Log both raw values with units at the call site to diagnose unit/skew issues"],"exampleFix":"// before\nlong end = System.currentTimeMillis(); // millis, smaller than nano start\nspan.setTraceTime(SpanVersion.TRACE_V3, startNanos, end, elapsed); // throws\n// after\nlong end = TimeUnit.MILLISECONDS.toNanos(System.currentTimeMillis());\nif (end < startNanos) { end = startNanos; }\nspan.setTraceTime(SpanVersion.TRACE_V3, startNanos, end, elapsed);","handlingStrategy":"validation","validationCode":"if (endTime < startTime) { log.warn(\"end {} before start {}\", endTime, startTime); endTime = startTime; }","typeGuard":"boolean isConsistentInterval(long start, long end) { return end >= start; }","tryCatchPattern":"try { span.setTraceTime(version, start, end, elapsed); } catch (IllegalArgumentException e) { log.warn(\"invalid interval {}..{}: {}\", start, end, e.getMessage()); }","preventionTips":["Use one time unit (epoch nanos for V3) everywhere","Apply clock-skew correction when timestamps come from multiple hosts","Sanity-check intervals at deserialization time"],"tags":["java","span","time","validation"],"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"}