{"record":{"id":"4052dafda2418cf4","repo":"grpc/grpc-go","slug":"protocol-q-v","errorCode":null,"errorMessage":"protocol %q: %v","messagePattern":"protocol %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/alts/internal/conn/record.go","lineNumber":151,"sourceCode":"\tconstPool constBufferPool // stored as a field to avoid heap allocations.\n}\n\n// NewConn creates a new secure channel instance given the other party role and\n// handshaking result.\nfunc NewConn(c net.Conn, side core.Side, recordProtocol string, key []byte, protected []byte) (net.Conn, error) {\n\treturn NewConnWithMaxFrameSize(c, side, recordProtocol, key, protected, 0)\n}\n\n// NewConnWithMaxFrameSize creates a new secure channel instance given the\n// other party role, handshaking result, and negotiated maximum frame size.\nfunc NewConnWithMaxFrameSize(c net.Conn, side core.Side, recordProtocol string, key []byte, protected []byte, negotiatedMaxFrameSize int) (net.Conn, error) {\n\tnewCrypto := protocols[recordProtocol]\n\tif newCrypto == nil {\n\t\treturn nil, fmt.Errorf(\"negotiated unknown next_protocol %q\", recordProtocol)\n\t}\n\tcrypto, err := newCrypto(side, key)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"protocol %q: %v\", recordProtocol, err)\n\t}\n\toverhead := MsgLenFieldSize + msgTypeFieldSize + crypto.EncryptionOverhead()\n\n\t// Clamp maxRecordLen to be at least altsRecordDefaultLength.\n\tmaxRecordLen := max(altsRecordDefaultLength, negotiatedMaxFrameSize)\n\tpayloadLengthLimit := maxRecordLen - overhead\n\t// We pre-allocate protected to be of size 32KB during initialization.\n\t// We increase the size of the buffer by the required amount if it can't\n\t// hold a complete encrypted record.\n\tprotectedHandle := readBufPool.Get(max(altsReadBufferInitialSize, len(protected)))\n\tprotectedBuf := *protectedHandle\n\t// Copy additional data from hanshaker service.\n\tcopy(protectedBuf, protected)\n\tprotectedBuf = protectedBuf[:len(protected)]\n\n\taltsConn := &conn{\n\t\tConn:               c,\n\t\treader:             readyreader.New(c),","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/credentials/alts/internal/conn/record.go#L133-L169","documentation":"Returned by conn.NewConnWithMaxFrameSize when the ALTSRecordFunc for the negotiated protocol was found and invoked, but returned an error during construction of the crypto instance. The wrapped error (%v) is the underlying crypto error. For the built-in ALTSRP_GCM_AES128_REKEY this means conn.NewAES128GCMRekey(side, key) failed.","triggerScenarios":"The ALTS handshake delivers a key of incorrect length or invalid content for AES-128-GCM-Rekey, so NewAES128GCMRekey returns an error when deriving counters or setting up the AEAD. Reached during doHandshake -> NewConnWithMaxFrameSize on GCP.","commonSituations":"The handshaker service returned truncated or malformed key data; a custom ALTS record implementation with a bug in its constructor; memory corruption on the handshaker RPC; an interoperability issue with a non-Go handshaker that produces keys of a different size.","solutions":["Inspect the wrapped error message — for AES128GCMRekey it usually indicates a key-length problem; compare against the expected 44 bytes (keyLength map).","Verify the GCP handshaker service and grpc-go versions are compatible.","File a grpc-go issue with the wrapped error if the handshaker service is the standard GCP one and key data appears malformed.","If using a custom ALTSRecordFunc, debug its constructor's validation logic."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Crypto construction failures during ALTS setup are unrecoverable for the connection.\n// Log the wrapped error and fail the RPC; gRPC will reconnect.\nif err != nil {\n    log.Printf(\"ALTS crypto setup failed: %v\", err)\n    return err\n}","preventionTips":["Ensure handshaker service and grpc-go versions are compatible so key sizes match (44 bytes for AES128GCMRekey).","When writing a custom ALTSRecordFunc, validate key length up front and return a clear error.","Capture the wrapped error in logs to diagnose key-material issues."],"tags":["grpc","alts","crypto","handshake","key-material"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}