grpc/grpc-go · error
received the frame length %d larger than the limit %d
Error message
received the frame length %d larger than the limit %d
What it means
ParseFramedMsg (common.go:54-62) reads the 4-byte little-endian frame length header from an ALTS record and rejects frames whose declared length exceeds maxLen. On the record path maxLen is altsRecordLengthLimit (1 MiB). This guards against memory-exhaustion / oversized-record attacks on the ALTS secure channel.
Source
Thrown at credentials/alts/internal/conn/common.go:62
} else {
head = make([]byte, total)
copy(head, in)
}
tail = head[len(in):]
return head, tail
}
// ParseFramedMsg parse the provided buffer and returns a frame of the format
// msgLength+msg and any remaining bytes in that buffer.
func ParseFramedMsg(b []byte, maxLen uint32) ([]byte, []byte, error) {
// If the size field is not complete, return the provided buffer as
// remaining buffer.
length, sufficientBytes := parseMessageLength(b)
if !sufficientBytes {
return nil, b, nil
}
if length > maxLen {
return nil, nil, fmt.Errorf("received the frame length %d larger than the limit %d", length, maxLen)
}
if len(b) < int(length)+4 { // account for the first 4 msg length bytes.
// Frame is not complete yet.
return nil, b, nil
}
return b[:MsgLenFieldSize+length], b[MsgLenFieldSize+length:], nil
}
// parseMessageLength returns the message length based on frame header. It also
// returns a boolean indicating if the buffer contains sufficient bytes to parse
// the length header. If there are insufficient bytes, (0, false) is returned.
func parseMessageLength(b []byte) (uint32, bool) {
if len(b) < MsgLenFieldSize {
return 0, false
}
msgLenField := b[:MsgLenFieldSize]
return binary.LittleEndian.Uint32(msgLenField), true
}View on GitHub (pinned to 03255a9237)
Solutions
- Ensure the peer uses a compatible, uncorrupted ALTS record implementation.
- If this is a test, lower the amount of data per record to stay under 1 MiB.
- Treat this as a connection-fatal error: close and re-establish the ALTS connection.
Example fix
// before: test sends a frame of 2 MiB // after: keep ALTS records <= 1 MiB (altsRecordLengthLimit) frame := makeFrame(payload[:1<<20])
Defensive patterns
Strategy: try-catch
Try / catch
if _, _, err := conn.ParseFramedMsg(buf, altsRecordLengthLimit); err != nil {
// oversized/malformed ALTS record: tear down the connection
log.Printf("closing ALTS conn: %v", err)
altsConn.Close()
} Prevention
- Treat oversized-frame errors as fatal and reconnect.
- Ensure peers emit ALTS records <= 1 MiB.
- Fuzz-test your ALTS endpoint with oversized frames to confirm it rejects them.
When it happens
Trigger: The ALTS peer (or a man-in-the-middle / corrupted stream) sends a record whose length header claims > 1 MiB. The read loop in record.go calls ParseFramedMsg on each chunk and surfaces this.
Common situations: A buggy or malicious peer; stream corruption after a TLS/ALTS failure; an interop test sending an oversized frame; a protocol implementation mismatch producing giant records.
Related errors
- received frame with incorrect message type %v, expected lowe
- server-side RPC versions are not compatible with this client
- client-side RPC versions is not compatible with this server,
- negotiated unknown next_protocol %q
- protocol %q: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/22fee33de8dad484.
Report an issue: GitHub.