grpc/grpc-go · error
unknown resulted record protocol %v
Error message
unknown resulted record protocol %v
What it means
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.
Source
Thrown at credentials/alts/internal/handshaker/handshaker.go:290
}
}
var extra []byte
if req.GetServerStart() != nil {
if resp.GetBytesConsumed() > uint32(len(req.GetServerStart().GetInBytes())) {
return nil, nil, errOutOfBound
}
extra = req.GetServerStart().GetInBytes()[resp.GetBytesConsumed():]
}
result, extra, err := h.processUntilDone(resp, extra)
if err != nil {
return nil, nil, err
}
// The handshaker returns a 128 bytes key. It should be truncated based
// on the returned record protocol.
keyLen, ok := keyLength[result.RecordProtocol]
if !ok {
return nil, nil, fmt.Errorf("unknown resulted record protocol %v", result.RecordProtocol)
}
maxFrameSize := int(envconfig.ALTSMaxFrameSize)
if peerMax := int(result.GetMaxFrameSize()); peerMax > 0 {
maxFrameSize = min(peerMax, maxFrameSize)
}
sc, err := conn.NewConnWithMaxFrameSize(h.conn, h.side, result.GetRecordProtocol(), result.KeyData[:keyLen], extra, maxFrameSize)
if err != nil {
return nil, nil, err
}
return sc, result, nil
}
func (h *altsHandshaker) accessHandshakerService(req *altspb.HandshakerReq) (*altspb.HandshakerResp, error) {
if err := h.stream.Send(req); err != nil {
return nil, fmt.Errorf("failed to send ALTS handshaker request: %w", err)
}
resp, err := h.stream.Recv()
if err != nil {View on GitHub (pinned to 03255a9237)
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.
Example fix
// before: stale grpc-go require google.golang.org/grpc v1.50.0 // after: upgrade to a release supporting the handshaker's protocol require google.golang.org/grpc v1.66.0
Defensive patterns
Strategy: validation
Validate before calling
// Ensure the negotiated record protocol is registered before consuming the result.
func supportedRecordProtocol(name string) bool {
switch name {
case "ALTSRP_GCM_AES128_REKEY":
return true
}
return false
} Try / catch
_, result, err := h.doHandshake(req)
if err != nil && strings.Contains(err.Error(), "unknown resulted record protocol") {
// version mismatch: upgrade grpc-go; not retryable on this build.
return fmt.Errorf("alts record protocol unsupported by this grpc-go version: %w", err)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- protocol %q: %v
- %v
- failed to send ALTS handshaker request: %w
- failed to receive ALTS handshaker response: %w
- xds: CertificateProvider to fetch trusted roots is missing,
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/378123f67a3c293d.
Report an issue: GitHub.