go data_error ai_generated true

proto: cannot parse invalid wire-format data

ID: go/proto-unmarshal-cannot-parse-invalid-wire-format

Also available as: JSON · Markdown · 中文
80%Fix Rate
86%Confidence
0Evidence
2024-05-09First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
google.golang.org/protobuf 1.28+ active — — —

Root Cause

proto.Unmarshal received bytes that are not valid protobuf wire format for the target message type. Typical causes: the payload is JSON/plain text, it was truncated, it's a different message type, or a length-delimited field has a corrupt varint length prefix.

generic

中文

proto.Unmarshal 收到的字节对于目标消息类型不是有效的 protobuf wire format。典型原因:负载是 JSON/纯文本、被截断、是另一种消息类型,或某个长度分隔字段的 varint 长度前缀已损坏。

Workarounds

  1. 85% success
    Validate and log the raw bytes before unmarshaling, and confirm the wire type matches:
    
    if len(data) == 0 { return errors.New("empty payload") }
    if err := proto.Unmarshal(data, msg); err != nil {
        log.Printf("unmarshal failed, first 32 bytes: %x", data[:min(32,len(data))])
        return fmt.Errorf("bad proto payload: %w", err)
    }
  2. 80% success
    Ensure the sender and receiver use the same generated message and that framing (length prefix) is stripped correctly, e.g. with a length-delimited reader:
    
    r := protoio.NewDelimitedReader(conn, 1<<20)
    msg := &pb.Foo{}
    if err := r.ReadMsg(msg); err != nil { return err }

Dead Ends

Common approaches that don't work:

  1. 98% fail

    Wire-format parsing is deterministic; identical bytes always fail identically. Retrying wastes CPU and never succeeds.

  2. 75% fail

    If the bytes are binary protobuf, protojson will reject them; if they are JSON, the original proto.Unmarshal was simply the wrong parser choice — the fix is picking the right one, not blindly swapping.