{"record":{"id":"22fee33de8dad484","repo":"grpc/grpc-go","slug":"received-the-frame-length-d-larger-than-the-limit","errorCode":null,"errorMessage":"received the frame length %d larger than the limit %d","messagePattern":"received the frame length (.+?) larger than the limit (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/alts/internal/conn/common.go","lineNumber":62,"sourceCode":"\t} else {\n\t\thead = make([]byte, total)\n\t\tcopy(head, in)\n\t}\n\ttail = head[len(in):]\n\treturn head, tail\n}\n\n// ParseFramedMsg parse the provided buffer and returns a frame of the format\n// msgLength+msg and any remaining bytes in that buffer.\nfunc ParseFramedMsg(b []byte, maxLen uint32) ([]byte, []byte, error) {\n\t// If the size field is not complete, return the provided buffer as\n\t// remaining buffer.\n\tlength, sufficientBytes := parseMessageLength(b)\n\tif !sufficientBytes {\n\t\treturn nil, b, nil\n\t}\n\tif length > maxLen {\n\t\treturn nil, nil, fmt.Errorf(\"received the frame length %d larger than the limit %d\", length, maxLen)\n\t}\n\tif len(b) < int(length)+4 { // account for the first 4 msg length bytes.\n\t\t// Frame is not complete yet.\n\t\treturn nil, b, nil\n\t}\n\treturn b[:MsgLenFieldSize+length], b[MsgLenFieldSize+length:], nil\n}\n\n// parseMessageLength returns the message length based on frame header. It also\n// returns a boolean indicating if the buffer contains sufficient bytes to parse\n// the length header. If there are insufficient bytes, (0, false) is returned.\nfunc parseMessageLength(b []byte) (uint32, bool) {\n\tif len(b) < MsgLenFieldSize {\n\t\treturn 0, false\n\t}\n\tmsgLenField := b[:MsgLenFieldSize]\n\treturn binary.LittleEndian.Uint32(msgLenField), true\n}","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/credentials/alts/internal/conn/common.go#L44-L80","documentation":"Returned by conn.ParseFramedMsg during ALTS record reading when the 4-byte little-endian length field of an incoming framed message decodes to a value greater than the configured maximum (maxLen = altsRecordLengthLimit = 1 MiB). This protects the reader from allocating unbounded memory based on an untrusted length header.","triggerScenarios":"An ALTS peer sends (or the stream is corrupted into appearing to send) a frame whose length header claims a size > 1 MiB. ParseFramedMsg is called from conn.ReadOnReady on every read of an ALTS-secured connection.","commonSituations":"A malicious or buggy peer sending oversized frames; memory corruption / bit-flips on the wire producing a huge length value; an interoperability issue with a non-Go ALTS implementation that frames differently; a man-in-the-middle injecting garbage bytes.","solutions":["Verify the peer is a legitimate ALTS endpoint and not corrupted/malicious; check the peer's gRPC version and ALTS implementation.","Capture a packet trace (e.g. tcpdump) of the ALTS connection to inspect the offending frame header.","If you control the peer, ensure it never emits a single ALTS record larger than 1 MiB.","Treat this as a connection-fatal error: tear down the connection and let gRPC reconnect or fail the RPC."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// ALTS framing errors are connection-fatal; let gRPC tear down and reconnect.\n// In application RPC code, treat the RPC error with codes.Internal or unavailable:\nif st, ok := status.FromErr(err); ok {\n    switch st.Code() {\n    case codes.Unavailable, codes.Internal:\n        // connection broke (possibly oversize frame); retry with backoff\n    }\n}","preventionTips":["Monitor for sudden bursts of framing errors — they may indicate a malicious peer or corruption.","Ensure peers never emit ALTS records larger than 1 MiB.","Use GCP ALTS only with trusted GCP workloads to minimize malicious-frame risk."],"tags":["grpc","alts","framing","corruption","security","limits"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}