{"record":{"id":"ee15dc47326aa81e","repo":"pinpoint-apm/pinpoint","slug":"timekey-name-header-is-missing","errorCode":null,"errorMessage":"timeKey.name()+ header is missing","messagePattern":"timeKey\\.name\\(\\)\\+ header is missing","errorType":"exception","errorClass":"InvalidGrpcHeaderException","httpStatus":null,"severity":"error","filePath":"grpc/src/main/java/com/navercorp/pinpoint/grpc/server/HeaderExtractor.java","lineNumber":47,"sourceCode":"public class HeaderExtractor {\n    private static final int UNSPECIFIED_LENGTH = -1;\n\n    private final int idMaxLength;\n    private final int nameMaxLength;\n\n    public HeaderExtractor() {\n        this(PinpointConstants.AGENT_ID_MAX_LEN, PinpointConstants.AGENT_NAME_MAX_LEN);\n    }\n\n    public HeaderExtractor(int idMaxLength, int nameMaxLength) {\n        this.idMaxLength = idMaxLength;\n        this.nameMaxLength = nameMaxLength;\n    }\n\n    public long getTime(Metadata headers, Metadata.Key<String> timeKey) {\n        final String timeStr = headers.get(timeKey);\n        if (timeStr == null) {\n            throw new InvalidGrpcHeaderException(timeKey, timeKey.name() + \" header is missing\");\n        }\n        try {\n            // check number format\n            return Long.parseLong(timeStr);\n        } catch (NumberFormatException e) {\n            throw new IllegalArgumentException(\"unsupported format\");\n        }\n    }\n\n    public String getId(Metadata headers, Metadata.Key<String> idKey) {\n        final String id = headers.get(idKey);\n        if (id == null) {\n            throw new InvalidGrpcHeaderException(idKey, idKey.name() + \" header is missing\");\n        }\n        return validateId(id, idKey);\n    }\n\n    public String getName(Metadata headers, Metadata.Key<String> idKey) {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/grpc/src/main/java/com/navercorp/pinpoint/grpc/server/HeaderExtractor.java#L29-L65","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nMetadata headers = new Metadata();\nstub.call(request, headers);\n// after\nMetadata headers = new Metadata();\nheaders.put(Metadata.Key.of(\"agentStartTime\", Metadata.ASCII_STRING_MARSHALLER), String.valueOf(startTime));\nstub.call(request, headers);","handlingStrategy":"try-catch","validationCode":"// Caller-side check before the RPC\nString requiredKey = \"agentStartTime\";\nif (headers.get(Metadata.Key.of(requiredKey, Metadata.ASCII_STRING_MARSHALLER)) == null) {\n    throw new IllegalStateException(requiredKey + \" must be set before invoking gRPC call\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    long time = headerExtractor.getTime(headers, timeKey);\n} catch (InvalidGrpcHeaderException e) {\n    LOG.warn(\"Missing required header {} from peer {}\", e.getMessage(), peer);\n    // reject request or respond with INVALID_ARGUMENT\n}","preventionTips":["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."],"tags":["grpc","headers","metadata","protocol"],"backgroundTag":"missing-required-argument","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}