pinpoint-apm/pinpoint · error · IllegalStateException
unsupported message
Error message
unsupported message
What it means
StatGrpcDataSender's onDispatch consumer builds PStatMessage from queued MetricType data and throws IllegalStateException "unsupported message" when the converted message is not a stat type it supports (e.g. PAgentStat, PAgentUriStat). The stat gRPC stream only accepts stat messages.
Source
Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/sender/grpc/StatGrpcDataSender.java:95
final PStatMessage statMessage = PStatMessage.newBuilder().setAgentStat(agentStat).build();
stream.onNext(statMessage);
return;
}
if (message instanceof PCustomMetricMessage) {
final PCustomMetricMessage customMetricMessage = (PCustomMetricMessage) message;
logger.info("Message will not delivered. message:{}", message);
return;
}
if (message instanceof PAgentUriStat) {
final PAgentUriStat agentUriStat = (PAgentUriStat) message;
final PStatMessage statMessage = PStatMessage.newBuilder().setAgentUriStat(agentUriStat).build();
// TODO remove comment
stream.onNext(statMessage);
return;
}
throw new IllegalStateException("unsupported message " + message);
}
};
public StatGrpcDataSender(String host, int port,
int executorQueueSize,
MessageConverter<MetricType, GeneratedMessageV3> messageConverter,
ReconnectExecutor reconnectExecutor,
ChannelFactory channelFactory) {
super(host, port, executorQueueSize, messageConverter, channelFactory);
this.statStub = StatGrpc.newStub(managedChannel);
this.reconnectExecutor = Objects.requireNonNull(reconnectExecutor, "reconnectExecutor");
final Runnable reconnectJob = new NamedRunnable(ID) {
@Override
public void run() {
startStream();
}
};View on GitHub (pinned to 744c3d3075)
Solutions
- Send only stat/metric data to StatGrpcDataSender; route spans to SpanGrpcDataSender
- Add the new metric type to onDispatch's conversion chain if it should go on the stat stream
- Verify the configured MessageConverter<MetricType,...> produces the expected PStat payload types
Example fix
// before
if (message instanceof PAgentUriStat) { ... }
throw new IllegalStateException("unsupported message " + message);
// after
if (message instanceof PAgentUriStat) { ... }
else if (message instanceof PNewStatType) {
PStatMessage m = PStatMessage.newBuilder().setNewStat((PNewStatType) message).build();
stream.onNext(m);
return;
}
throw new IllegalStateException("unsupported message " + message); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(messageConverter.toMessage(data) instanceof PStatPayload)) { throw new IllegalStateException("StatGrpcDataSender only accepts stat data"); } Type guard
GeneratedMessageV3 msg = messageConverter.toMessage(data);
if (msg instanceof PAgentUriStat || msg instanceof PAgentStat) { /* safe to send as PStatMessage */ } Try / catch
try { dispatch(data); } catch (IllegalStateException e) { log.error("Unsupported message on stat stream: {}", data, e); } Prevention
- Separate span and stat senders behind distinct typed APIs
- Add exhaustive tests for each MetricType to PStat payload mapping
- Update onDispatch's type chain when adding new metrics
When it happens
Trigger: Dispatching a message through the stat sender whose converter output is not one of the handled PStat payloads — e.g. sending a PSpan or agent info through the stat stream.
Common situations: Swapped sender wiring (stat data to span sender or vice versa), a custom/updated MessageConverter returning an unexpected protobuf type, or new metric types not added to onDispatch's if/else chain.
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/c8e60d234b5a50ee.
Report an issue: GitHub.