pinpoint-apm/pinpoint · error · InvalidGrpcHeaderException
timeKey.name()+ header is missing
Error message
timeKey.name()+ header is missing
What it means
HeaderExtractor.getTime reads a required timestamp header (e.g. an agent start-time key) from incoming gRPC metadata; when the header is absent it throws InvalidGrpcHeaderException with '<name> header is missing'. The server cannot correlate the request without this header, so it fails fast instead of parsing null.
Solutions
- Upgrade/align the client and server (agent and collector) to matching versions so the required header is sent.
- Verify the client sets the exact metadata key (e.g. the timeKey name shown in the message) on every request.
- Check for intermediary proxies or interceptors stripping custom gRPC metadata headers.
- On the caller side, wrap calls to set the header before invoking the RPC.
Example fix
// before
Metadata headers = new Metadata();
stub.call(request, headers);
// after
Metadata headers = new Metadata();
headers.put(Metadata.Key.of("agentStartTime", Metadata.ASCII_STRING_MARSHALLER), String.valueOf(startTime));
stub.call(request, headers); Defensive patterns
Strategy: try-catch
Validate before calling
// Caller-side check before the RPC
String requiredKey = "agentStartTime";
if (headers.get(Metadata.Key.of(requiredKey, Metadata.ASCII_STRING_MARSHALLER)) == null) {
throw new IllegalStateException(requiredKey + " must be set before invoking gRPC call");
} Try / catch
try {
long time = headerExtractor.getTime(headers, timeKey);
} catch (InvalidGrpcHeaderException e) {
LOG.warn("Missing required header {} from peer {}", e.getMessage(), peer);
// reject request or respond with INVALID_ARGUMENT
} Prevention
- Keep agent and collector versions in sync so header protocol matches.
- Centralize metadata key construction so client and server use identical key names.
- Add an interceptor that asserts required headers before handlers run.
- Verify proxies/gateways forward custom metadata headers.
When it happens
Trigger: A gRPC client (e.g. an older Pinpoint agent or non-Pinpoint client) sends a request to the collector without setting the required time metadata key that getTime expects; the Metadata passed to getTime lacks the key entirely.
Common situations: Agent/server version mismatch where one side stopped sending the time header; header key name mismatch between client and server (case-sensitive ASCII keys in Metadata); a custom or third-party client not replicating Pinpoint's header protocol; proxies/interceptors stripping metadata.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- INTERNAL_SERVER_ERROR
- agentDataSender close fail
- can't find SslProvider. value:+providerType
- cipherSuite+ is not safe. Please check this…
- cipherSuites must not be empty
AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07).
Data as JSON: /api/errors/ee15dc47326aa81e.
Report an issue: GitHub.
Appendix: source
Thrown at grpc/src/main/java/com/navercorp/pinpoint/grpc/server/HeaderExtractor.java:47
public class HeaderExtractor {
private static final int UNSPECIFIED_LENGTH = -1;
private final int idMaxLength;
private final int nameMaxLength;
public HeaderExtractor() {
this(PinpointConstants.AGENT_ID_MAX_LEN, PinpointConstants.AGENT_NAME_MAX_LEN);
}
public HeaderExtractor(int idMaxLength, int nameMaxLength) {
this.idMaxLength = idMaxLength;
this.nameMaxLength = nameMaxLength;
}
public long getTime(Metadata headers, Metadata.Key<String> timeKey) {
final String timeStr = headers.get(timeKey);
if (timeStr == null) {
throw new InvalidGrpcHeaderException(timeKey, timeKey.name() + " header is missing");
}
try {
// check number format
return Long.parseLong(timeStr);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("unsupported format");
}
}
public String getId(Metadata headers, Metadata.Key<String> idKey) {
final String id = headers.get(idKey);
if (id == null) {
throw new InvalidGrpcHeaderException(idKey, idKey.name() + " header is missing");
}
return validateId(id, idKey);
}
public String getName(Metadata headers, Metadata.Key<String> idKey) {View on GitHub (pinned to 744c3d3075)