{"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/03255a9237b6eb32710f6bc4f2de9a675b99fe36/credentials/alts/internal/conn/record.go#L133-L169","documentation":"NewConnWithMaxFrameSize (record.go:149-151) found the protocol factory but the factory function newCrypto(side, key) returned an error constructing the cipher (e.g. AES-GCM AEAD creation). The error is wrapped as \"protocol %q: %v\". The key/side passed come from the handshake result.","triggerScenarios":"The ALTS handshake produced a key that the record protocol's crypto factory rejects — wrong key length, nil key, or an AEAD construction failure for the negotiated protocol (e.g. ALTSRP_GCM).","commonSituations":"A corrupted or truncated session key from the handshaker service; a custom crypto factory with strict key-length requirements; an interop mismatch producing a malformed key.","solutions":["Inspect the inner %v for the cipher-specific cause (key length, AEAD init).","Ensure both peers use a compatible ALTS record protocol and key derivation.","Re-establish the ALTS handshake; if persistent, align gRPC/ALTS versions on both ends."],"exampleFix":"// before: handshaker returns a 16-byte key for a 32-byte AEAD\n// after: align record protocol and key derivation so newCrypto succeeds\n// (upgrade gRPC on both sides; do not hand-craft ALTS keys)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"c, err := conn.NewConnWithMaxFrameSize(raw, core.ClientSide, rp, key, protected, 0)\nif err != nil {\n    // inner %v explains the cipher failure (e.g. key length)\n    log.Printf(\"ALTS crypto init failed for %q: %v\", rp, err)\n    return nil, err\n}","preventionTips":["Never hand-construct ALTS keys; let the handshaker produce them.","Align record protocol and key derivation across both peers.","Re-run the handshake on transient crypto-init failures."],"tags":["go","grpc","alts","crypto","security"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}