pinpoint-apm/pinpoint · error · IllegalStateException
unsupported message
Error message
unsupported message
What it means
SpanGrpcDataSender's onDispatch consumer converts queued MetricType data to protobuf and requires a PSpan-capable message; if the converted message is neither a supported span type it throws IllegalStateException "unsupported message". The stream only accepts span messages, so other types are a programming/routing error.
Source
Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/grpc/SpanGrpcDataSender.java:87
final GeneratedMessageV3 message = messageConverter.toMessage(data);
if (isDebug) {
logger.debug("Send message={}", debugLog(message));
}
if (message instanceof PSpanChunk) {
final PSpanChunk spanChunk = (PSpanChunk) message;
final PSpanMessage spanMessage = PSpanMessage.newBuilder().setSpanChunk(spanChunk).build();
stream.onNext(spanMessage);
attemptRenew();
return;
}
if (message instanceof PSpan) {
final PSpan pSpan = (PSpan) message;
final PSpanMessage spanMessage = PSpanMessage.newBuilder().setSpan(pSpan).build();
stream.onNext(spanMessage);
attemptRenew();
return;
}
throw new IllegalStateException("unsupported message " + data);
}
};
public SpanGrpcDataSender(String host, int port,
int executorQueueSize,
MessageConverter<SpanType, GeneratedMessageV3> messageConverter,
ReconnectExecutor reconnectExecutor,
ChannelFactory channelFactory,
StreamState failState,
long maxRpcAgeMillis) {
super(host, port, executorQueueSize, messageConverter, channelFactory);
this.spanStub = SpanGrpc.newStub(managedChannel);
this.interval = newIntervalFunction(maxRpcAgeMillis);
this.rpcExpiredAt = new AtomicLong(System.currentTimeMillis());
this.reconnectExecutor = Objects.requireNonNull(reconnectExecutor, "reconnectExecutor");View on GitHub (pinned to 744c3d3075)
Solutions
- Send only span-type data (converting to PSpan/PSpanMessage) to SpanGrpcDataSender
- Route stat/metric data to StatGrpcDataSender instead
- Extend onDispatch to handle and convert the new message type if it belongs on the span stream
Example fix
// before spanSender.send(agentUriStat); // after statSender.send(agentUriStat);
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(messageConverter.toMessage(data) instanceof PSpan)) { throw new IllegalStateException("SpanGrpcDataSender only accepts span data"); } Type guard
GeneratedMessageV3 msg = messageConverter.toMessage(data);
if (msg instanceof PSpan pSpan) { stream.onNext(PSpanMessage.newBuilder().setSpan(pSpan).build()); } Try / catch
try { dispatch(data); } catch (IllegalStateException e) { log.error("Unsupported message on span stream: {}", data, e); } Prevention
- Route stat/URI-stat data to StatGrpcDataSender, spans only to the span sender
- Type the data queues per sender to make wrong routing a compile-time issue
- Extend onDispatch whenever new span-ish payloads are introduced
When it happens
Trigger: Dispatching a data object through SpanGrpcDataSender whose messageConverter output is not the expected PSpan (or sibling span message) — e.g. sending a SpanChunk/agent URI stat to the span sender.
Common situations: Misconfigured sender wiring where span and stat senders are swapped, a custom MessageConverter returning an unexpected message type, or new telemetry types routed to the span stream without updating onDispatch.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- list size not same
- spanEventList is empty.
- first SpanEvent is null
- unsupported type:${dataType}
- Unexpected TraceId type: ${traceId}
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/03ffb186522539c7.
Report an issue: GitHub.