pinpoint-apm/pinpoint · error · IllegalStateException

first SpanEvent is null

Error message

first SpanEvent is null

What it means

After confirming the spanEventList is non-empty, getKeyTime asserts that the first element is not null and throws IllegalStateException if it is. The list is expected to contain real SpanEvent objects; a null first element means the internal event list was populated with a null entry, violating the profiler's invariants.

Source

Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/context/compress/GrpcSpanProcessorV2.java:132

                if (currentDepth == prevDepth) {
                    // skip
                    pSpanEvent.setDepth(0);
                } else {
                    pSpanEvent.setDepth(currentDepth);
                }
                prevDepth = currentDepth;
            }
        }
    }


    private long getKeyTime(List<SpanEvent> spanEventList) {
        if (CollectionUtils.isEmpty(spanEventList)) {
            throw new IllegalArgumentException("spanEventList is empty.");
        }
        final SpanEvent first = spanEventList.get(0);
        if (first == null) {
            throw new IllegalStateException("first SpanEvent is null");
        }

        return first.getStartTime();
    }

}

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Find and fix code that adds null SpanEvents to the event list before span serialization.
  2. Filter nulls before passing the list: events.removeIf(Objects::isNull) or use a non-null-allowing collection during trace recording.
  3. Check for concurrent modification of the span event list (race between event add/clear and flush).
  4. If reproducible, capture the trace and report to Pinpoint with the plugin/interceptor in use.

Example fix

// before
List<SpanEvent> events = span.getSpanEventList();
long keyTime = grpcSpanProcessor.keyTime(events);

// after
List<SpanEvent> events = span.getSpanEventList();
events.removeIf(Objects::isNull);
long keyTime = events.isEmpty() ? span.getStartTime() : events.get(0).getStartTime();
Defensive patterns

Strategy: validation

Validate before calling

if (spanEventList != null && !spanEventList.isEmpty() && spanEventList.get(0) == null) {
    spanEventList.removeIf(Objects::isNull); // sanitize before key-time computation
}

Try / catch

try {
    long keyTime = processor.keyTime(span.getSpanEventList());
} catch (IllegalStateException e) {
    logger.warn("Null SpanEvent in list for span {}", span.getSpanId(), e);
    keyTime = span.getStartTime();
}

Prevention

When it happens

Trigger: Calling keyTime() with a List<SpanEvent> whose element at index 0 is null — e.g. code that added null to the event list, or a list implementation that pads/truncates leaving nulls.

Common situations: Custom instrumentation or plugins inserting null SpanEvents into the trace context; reflection/manual list manipulation; corrupted trace state after concurrent modification of the event list.

Related errors


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