pinpoint-apm/pinpoint · error · StatusException
INVALID_ARGUMENT
INVALID_ARGUMENT
Error message
handleCommand() not support included Header:{}. Connection will be disconnected. What it means
Pinpoint's legacy gRPC command channel (handleCommand, the v1 API) requires that the agent's connection Header NOT carry a supportCommandCodeList; the sentinel SUPPORT_COMMAND_CODE_LIST_NOT_EXIST means the field is absent. If the agent sends a non-empty support command code list in the header, the collector treats this as a protocol violation for the v1 stream, logs a warning, fails the call with gRPC Status.INVALID_ARGUMENT, and disconnects the connection.
Source
Thrown at realtime/realtime-collector/src/main/java/com/navercorp/pinpoint/realtime/collector/receiver/grpc/GrpcCommandService.java:92
this.activeThreadDumpSinkRepo = Objects.requireNonNull(activeThreadDumpSinkRepo, "activeThreadDumpSinkRepo");
this.activeThreadLightDumpSinkRepo = Objects.requireNonNull(activeThreadLightDumpSinkRepo, "activeThreadLightDumpSinkRepo");
this.echoSinkRepo = Objects.requireNonNull(echoSinkRepo, "echoSinkRepo");
}
@Override
@SuppressWarnings("deprecation")
public StreamObserver<PCmdMessage> handleCommand(StreamObserver<PCmdRequest> requestObserver) {
final Context context = Context.current();
Long transportId = getTransportIdFromContext(context);
final Header header = ServerContext.getAgentInfo(context);
ClusterKey clusterKey = getClusterKeyFromContext(header);
logger.info("{} => local. handleCommand(). transportId:{}.", clusterKey, transportId);
List<Integer> supportCommandCodeList = header.getSupportCommandCodeList();
if (supportCommandCodeList != Header.SUPPORT_COMMAND_CODE_LIST_NOT_EXIST) {
logger.warn(
"handleCommand() not support included Header:{}. Connection will be disconnected.",
Header.SUPPORT_COMMAND_CODE.name()
);
requestObserver.onError(new StatusException(Status.INVALID_ARGUMENT));
return DisabledStreamObserver.instance();
}
AtomicReference<GrpcAgentConnection> connRef = new AtomicReference<>();
ServerCallStreamObserver<PCmdRequest> serverCallStreamObserver =
(ServerCallStreamObserver<PCmdRequest>) requestObserver;
serverCallStreamObserver.setOnCancelHandler(() -> {
GrpcAgentConnection conn = connRef.get();
if (conn != null) {
this.agentConnectionRepository.remove(conn);
}
});View on GitHub (pinned to 744c3d3075)
Solutions
- Upgrade the collector to a version that supports handleCommandV2, or downgrade the agent so it does not send supportCommandCodeList on the v1 stream
- If implementing a custom client on handleCommand, omit the supportCommandCodeList header field entirely (leave SUPPORT_COMMAND_CODE_LIST_NOT_EXIST)
- Verify agent/collector version compatibility for the profiler command service and align them to the same protocol version
- Check which collector instance the agent is connecting to (routing/LB may send it to a legacy collector)
Example fix
// before (agent on v1 stream sends command codes)
Header header = Header.newBuilder()
.setName(agentName)
.addAllSupportCommandCodeList(supportCommandCodeList) // rejected by handleCommand
.build();
// after (use v2 stream, or omit codes on v1)
// either call profilerCommandStub.handleCommandV2(header with codes)
// or for legacy handleCommand:
Header header = Header.newBuilder()
.setName(agentName) // no supportCommandCodeList
.build(); Defensive patterns
Strategy: validation
Validate before calling
// client-side, before opening the v1 command stream
if (!header.getSupportCommandCodeList().isEmpty()) {
throw new IllegalStateException("supportCommandCodeList must be omitted for handleCommand (v1); use handleCommandV2");
} Try / catch
// server/clients observing the stream failure
try (CommandStream stream = openCommandStream(header)) {
stream.awaitReady();
} catch (StatusRuntimeException e) {
if (e.getStatus().getCode() == Status.Code.INVALID_ARGUMENT) {
log.warn("v1 command stream rejected: header must not contain supportCommandCodeList", e);
}
} Prevention
- Never set supportCommandCodeList in the Header when using the legacy handleCommand stream
- Use handleCommandV2 when the agent needs to advertise supported command codes
- Keep agent and collector versions aligned on the same command protocol
- Fail fast in custom agent code: assert header contents match the stream version being opened
When it happens
Trigger: An agent (or agent-like client) opens the ProfilerCommandService handleCommand stream while its Handshake/Header includes a populated supportCommandCodeList field instead of omitting it. In Pinpoint this happens when a newer agent built for the v2 API (handleCommandV2) connects to a collector that only registers/serves the legacy v1 handler.
Common situations: Version mismatch between pinpoint agent and collector: agent upgraded to the command-v2 protocol but collector still on the old version (or vice versa routing to the wrong endpoint). Custom/prototype agents copying Header building code and setting SUPPORT_COMMAND_CODE_LIST even when using the v1 stream.
Understand the failure class
Background: "must be a positive integer", "cannot be empty", "invalid argument": how invalid-argument errors work across open-source libraries — this error's family across 33 libraries.
Related errors
- list size not same
- Failed to request. {} header={}
- Failed to request. header={}
- Failed to request. header={}
- PTransactionId is not set
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/1c31b80f322e1577.
Report an issue: GitHub.