chenhg5/cc-connect · error

yuanbao: length %d exceeds data at %d

Error message

yuanbao: length %d exceeds data at %d

What it means

Thrown by parseFields when a length-delimited field declares a length (ln) that extends past the end of the available data: pos+ln > len(data). This means the message is internally inconsistent — the declared length cannot be satisfied — so the decoder aborts rather than produce a corrupt []byte.

Source

Thrown at platform/yuanbao/proto.go:160

		pos += n
		fieldNum := int(tag >> 3)
		wt := int(tag & 0x07)
		switch wt {
		case wtVarint:
			val, n := decodeVarint(data[pos:])
			if n == 0 {
				return nil, fmt.Errorf("yuanbao: parse varint at %d", pos)
			}
			fields = append(fields, field{fieldNum, wt, val})
			pos += n
		case wtLen:
			ln, n := decodeVarint(data[pos:])
			if n == 0 {
				return nil, fmt.Errorf("yuanbao: parse length at %d", pos)
			}
			pos += n
			if pos+int(ln) > len(data) {
				return nil, fmt.Errorf("yuanbao: length %d exceeds data at %d", ln, pos)
			}
			val := make([]byte, ln)
			copy(val, data[pos:pos+int(ln)])
			fields = append(fields, field{fieldNum, wt, val})
			pos += int(ln)
		case wt64Bit:
			if pos+8 > len(data) {
				return nil, fmt.Errorf("yuanbao: 64-bit truncated at %d", pos)
			}
			fields = append(fields, field{fieldNum, wt, binary.LittleEndian.Uint64(data[pos : pos+8])})
			pos += 8
		case wt32Bit:
			if pos+4 > len(data) {
				return nil, fmt.Errorf("yuanbao: 32-bit truncated at %d", pos)
			}
			fields = append(fields, field{fieldNum, wt, uint64(binary.LittleEndian.Uint32(data[pos : pos+4]))})
			pos += 4
		default:

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Verify frames are correctly delimited before decoding; do not feed a byte stream that may contain multiple or partial frames.
  2. Log ln and pos plus a hex dump of data to check for desynchronization from an earlier misparse.
  3. Confirm the payload is not compressed/encrypted — decompress/decrypt before parseFields.
  4. If an earlier field parse could desync the cursor, validate the whole message with a stricter parser or resync from the frame boundary.
  5. Check the yuanbao server version for wire-format changes.

Example fix

// before
body := frame.Data // may contain header prefix
cm, err := decodeConnMsg(body)
// after
if !frame.IsProtobufBody { // skip compressed/heartbeat frames
    return nil
}
cm, err := decodeConnMsg(frame.Payload)
if err != nil {
    slog.Warn("yuanbao: bad frame, resyncing", "err", err)
    return nil
}
Defensive patterns

Strategy: validation

Validate before calling

func plausibleLength(b []byte, pos int) bool {
    if pos >= len(b) { return false }
    ln, n := decodeVarint(b[pos:])
    return n > 0 && pos+n+int(ln) <= len(b)
}

Try / catch

fields, err := parseFields(data)
if err != nil {
    slog.Warn("yuanbao: overlong length field, resyncing", "err", err)
    stream.ResyncToNextFrame()
    return
}

Prevention

When it happens

Trigger: A wire-type-2 field whose length prefix says e.g. 500 bytes but only 30 remain; caused by byte-stream desynchronization (parser misaligned after a bad earlier field), corruption, or a truncated frame where the length varint survived but the payload did not. Also possible if a huge/corrupt length is parsed from garbage bytes.

Common situations: Merging raw TCP bytes into frames incorrectly, decoding a compressed/encrypted body as raw protobuf, server protocol change shifting field boundaries, or a malicious/corrupt upstream payload with a forged length.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/728496589d8bc940. Report an issue: GitHub.