{"record":{"id":"378123f67a3c293d","repo":"grpc/grpc-go","slug":"unknown-resulted-record-protocol-v","errorCode":null,"errorMessage":"unknown resulted record protocol %v","messagePattern":"unknown resulted record protocol (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/alts/internal/handshaker/handshaker.go","lineNumber":290,"sourceCode":"\t\t}\n\t}\n\n\tvar extra []byte\n\tif req.GetServerStart() != nil {\n\t\tif resp.GetBytesConsumed() > uint32(len(req.GetServerStart().GetInBytes())) {\n\t\t\treturn nil, nil, errOutOfBound\n\t\t}\n\t\textra = req.GetServerStart().GetInBytes()[resp.GetBytesConsumed():]\n\t}\n\tresult, extra, err := h.processUntilDone(resp, extra)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\t// The handshaker returns a 128 bytes key. It should be truncated based\n\t// on the returned record protocol.\n\tkeyLen, ok := keyLength[result.RecordProtocol]\n\tif !ok {\n\t\treturn nil, nil, fmt.Errorf(\"unknown resulted record protocol %v\", result.RecordProtocol)\n\t}\n\tmaxFrameSize := int(envconfig.ALTSMaxFrameSize)\n\tif peerMax := int(result.GetMaxFrameSize()); peerMax > 0 {\n\t\tmaxFrameSize = min(peerMax, maxFrameSize)\n\t}\n\tsc, err := conn.NewConnWithMaxFrameSize(h.conn, h.side, result.GetRecordProtocol(), result.KeyData[:keyLen], extra, maxFrameSize)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\treturn sc, result, nil\n}\n\nfunc (h *altsHandshaker) accessHandshakerService(req *altspb.HandshakerReq) (*altspb.HandshakerResp, error) {\n\tif err := h.stream.Send(req); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to send ALTS handshaker request: %w\", err)\n\t}\n\tresp, err := h.stream.Recv()\n\tif err != nil {","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/alts/internal/handshaker/handshaker.go#L272-L308","documentation":"After a successful ALTS handshake the result's RecordProtocol string is looked up in the local keyLength map (handshaker.go:288), which only knows ALTSRP_GCM_AES128_REKEY. If the handshaker service returned a different protocol name, this error fires. It is a client/server-vs-handshaker-service version incompatibility: the peer or handshaker service negotiated a record protocol this binary's conn package has not registered.","triggerScenarios":"doHandshake completes, result.RecordProtocol is not present in keyLength (currently only 'ALTSRP_GCM_AES128_REKEY'). Happens when the handshaker service has been upgraded to negotiate a newer record protocol (or a peer forced one) that the linked grpc-go version's altsRecordFuncs/keyLength map does not contain.","commonSituations":"Running an outdated grpc-go/credentials/alts module against a newer GCP handshaker service, or a peer pinned to a different ALTS record protocol. Also reproducible in forks that stripped the default protocol registration.","solutions":["Upgrade the google.golang.org/grpc module so credentials/alts knows the negotiated record protocol.","Ensure no custom code deregistered rekeyRecordProtocolName or overwrote conn.RegisterProtocol entries.","If running a fork, register the returned protocol name in both altsRecordFuncs and keyLength.","Match the grpc-go version across all peers in the mesh."],"exampleFix":"// before: stale grpc-go\nrequire google.golang.org/grpc v1.50.0\n\n// after: upgrade to a release supporting the handshaker's protocol\nrequire google.golang.org/grpc v1.66.0","handlingStrategy":"validation","validationCode":"// Ensure the negotiated record protocol is registered before consuming the result.\nfunc supportedRecordProtocol(name string) bool {\n    switch name {\n    case \"ALTSRP_GCM_AES128_REKEY\":\n        return true\n    }\n    return false\n}","typeGuard":null,"tryCatchPattern":"_, result, err := h.doHandshake(req)\nif err != nil && strings.Contains(err.Error(), \"unknown resulted record protocol\") {\n    // version mismatch: upgrade grpc-go; not retryable on this build.\n    return fmt.Errorf(\"alts record protocol unsupported by this grpc-go version: %w\", err)\n}","preventionTips":["Keep google.golang.org/grpc up to date across the fleet.","Do not fork or strip the default record-protocol registration.","Pin a grpc-go version known to interoperate with the handshaker service in your environment.","Monitor for new ALTS record protocols when upgrading the metadata-server side."],"tags":["alts","grpc","version-mismatch","crypto","handshake"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}