canopy-network/canopy · error

invalid field value at offset %d

Error message

invalid field value at offset %d

What it means

For a matching field with a non-bytes wire type (varint, fixed32, fixed64, etc.), GetRawProtoField consumes the value with protowire.ConsumeFieldValue. A negative result means the value bytes are malformed or the buffer ends inside the value — the wire data at this offset cannot be parsed as the declared wire type.

Source

Thrown at lib/codec/codec.go:100

					return nil, fmt.Errorf("invalid length at offset %d", offset)
				}
				// calculate the new offset
				offset += lenBytes
				// extract the field value bytes
				if offset+int(valueLen) > len(protoBytes) {
					return nil, fmt.Errorf("field value exceeds buffer bounds")
				}
				// make buffer to return
				fieldBytes := make([]byte, valueLen)
				// copy into the buffer
				copy(fieldBytes, protoBytes[offset:offset+int(valueLen)])
				// return the value
				return fieldBytes, nil
			} else {
				// for other wire types, consume the value directly
				valueLen := protowire.ConsumeFieldValue(fieldNum, wireType, protoBytes[offset:])
				if valueLen < 0 {
					return nil, fmt.Errorf("invalid field value at offset %d", offset)
				}
				if offset+valueLen > len(protoBytes) {
					return nil, fmt.Errorf("field value exceeds buffer bounds")
				}
				fieldBytes := make([]byte, valueLen)
				copy(fieldBytes, protoBytes[offset:offset+valueLen])
				return fieldBytes, nil
			}
		} else {
			// skip this field
			skipLen := protowire.ConsumeFieldValue(fieldNum, wireType, protoBytes[offset:])
			if skipLen < 0 {
				return nil, fmt.Errorf("invalid field value at offset %d", offset)
			}
			offset += skipLen
		}
	}
	return nil, fmt.Errorf("%w: %d", ErrFieldNotFound, fieldNumber)

View on GitHub (pinned to ee8197d91d)

Solutions

  1. Verify buffer integrity with proto.Unmarshal before raw scanning.
  2. Re-generate or re-fetch the message bytes from the source of truth.
  3. Check that no earlier manual byte manipulation shifted offsets.

Example fix

// before
raw, _ := codec.GetRawProtoField(foreignBytes, 1)
// after
if err := proto.Unmarshal(data, &msg); err != nil { return err }
raw, err := codec.GetRawProtoField(data, 1)
Defensive patterns

Strategy: validation

Validate before calling

var probe pb.Event
if err := proto.Unmarshal(data, &probe); err != nil {
    return fmt.Errorf("malformed wire data: %w", err)
}

Try / catch

raw, err := codec.GetRawProtoField(data, fieldNum)
if err != nil && strings.Contains(err.Error(), "invalid field value") {
    return fmt.Errorf("corrupt field encoding: %w", err)
}

Prevention

When it happens

Trigger: GetRawProtoField on corrupted/truncated wire bytes where the target field's value (e.g. a varint) is cut short or encodes an invalid pattern.

Common situations: Bit rot or corruption in stored blobs; passing a manually assembled byte slice; reading past a wrong offset because an earlier field was mis-sized.

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 canopy-network/canopy@ee8197d91d (2026-09-06). Data as JSON: /api/errors/53a9c5a6a0c2c0b0. Report an issue: GitHub.