pinpoint-apm/pinpoint · error · IllegalArgumentException

spanEventList is empty.

Error message

spanEventList is empty.

What it means

GrpcSpanProcessorV2.getKeyTime derives the key timestamp for a span's event list by taking the start time of the first SpanEvent. Before doing so it asserts the list is non-empty; if it is empty, it throws IllegalArgumentException because there is no event to derive a timestamp from. This is an internal invariant: the profiler's span compression pipeline expects at least one SpanEvent when computing the key time.

Source

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

                pSpanEvent.setDepth(depth);
            } else {
                int currentDepth = spanEvent.getDepth();

                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. Check why the Span reaching GrpcSpanProcessorV2 has an empty spanEventList; ensure at least one SpanEvent is added before the span is completed/flushed.
  2. Guard in calling code: if span.getSpanEventList() is empty, skip key-time computation or use the span's own start time.
  3. Upgrade Pinpoint agent — newer versions tolerate empty event lists in the compression pipeline.
  4. If a custom plugin/filter strips SpanEvents, fix the plugin to preserve at least the root event.

Example fix

// before
long keyTime = grpcSpanProcessor.keyTime(span.getSpanEventList());

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

Strategy: validation

Validate before calling

if (spanEventList == null || spanEventList.isEmpty()) {
    // skip key-time computation or fall back to span start time
    return span.getStartTime();
}

Try / catch

try {
    long keyTime = processor.keyTime(span.getSpanEventList());
} catch (IllegalArgumentException e) {
    logger.warn("Span {} has empty event list; using span start time", span.getSpanId(), e);
    keyTime = span.getStartTime();
}

Prevention

When it happens

Trigger: Calling keyTime() (via GrpcSpanProcessorV2 span processing during gRPC span serialization) with a List<SpanEvent> that has zero elements — e.g. a Span with no span events recorded before the span is flushed to the collector.

Common situations: Spans completed without any child events (async spans, filtered-out events, or tracing plugins that produce empty event lists); custom interceptors that remove or never add SpanEvents; races where events are cleared before the span is sent.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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