{"record":{"id":"1b4d775388ed0064","repo":"grpc/grpc-go","slug":"v","errorCode":null,"errorMessage":"%v","messagePattern":"%v","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/alts/internal/handshaker/handshaker.go","lineNumber":271,"sourceCode":"\t}\n\n\tconn, result, err := h.doHandshake(req)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\tauthInfo := authinfo.New(result)\n\treturn conn, authInfo, nil\n}\n\nfunc (h *altsHandshaker) doHandshake(req *altspb.HandshakerReq) (net.Conn, *altspb.HandshakerResult, error) {\n\tresp, err := h.accessHandshakerService(req)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\t// Check of the returned status is an error.\n\tif resp.GetStatus() != nil {\n\t\tif got, want := resp.GetStatus().Code, uint32(codes.OK); got != want {\n\t\t\treturn nil, nil, fmt.Errorf(\"%v\", resp.GetStatus().Details)\n\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 {","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/credentials/alts/internal/handshaker/handshaker.go#L253-L289","documentation":"Returned inside doHandshake when the ALTS handshaker service's response carries a non-nil Status with a code other than OK (codes.OK==0). The error message is simply the Status.Details string from the handshaker service, surfacing whatever reason the GCP handshaker service gave for failing the handshake.","triggerScenarios":"The DoHandshake RPC stream is open and a response was received, but resp.Status.Code != 0. Reached for both client and server handshakes during doHandshake -> accessHandshakerService. The actual reason is opaque (just the Details string), so the cause lives inside the metadata-server handshaker.","commonSituations":"The peer's target service account does not match any identity the handshaker service expects (TargetServiceAccounts mismatch on the client); the client identity is not allowed; access token rejection; the peer closed/aborted the handshake; resource/quota limits inside the handshaker service.","solutions":["Read the wrapped Details string for the handshaker service's explanation and act on it (e.g. identity/account mismatch).","For client handshakes, verify TargetServiceAccounts in ClientOptions match the server's service accounts.","Check the bound access token (BoundAccessToken) is valid and not expired.","Confirm both peers are on GCP and permitted to use ALTS; consult GCP IAM/ALTS policy.","Retry if the Details suggest a transient handshaker-service issue."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// The handshaker service's Status.Details is opaque; log it for diagnosis.\nif err != nil {\n    log.Printf(\"ALTS handshake rejected by handshaker service: %v\", err)\n    // Distinguish identity/account issues (non-retryable) from transient ones.\n    if strings.Contains(err.Error(), \"identity\") || strings.Contains(err.Error(), \"account\") {\n        return err // fix config, do not blindly retry\n    }\n    // otherwise allow a bounded retry\n}","preventionTips":["Verify TargetServiceAccounts (client) match the server's service accounts.","Ensure BoundAccessToken is valid and unexpired when used.","Check GCP IAM/ALTS policy permits both peers.","Log Status.Details to classify rejection reasons."],"tags":["grpc","alts","gcp","handshaker-service","auth","identity"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}