canopy-network/canopy · error

unsupported wire type %d

Error message

unsupported wire type %d

What it means

prelightProtoBytes walks raw protobuf bytes tag-by-tag before actual decoding and only recognizes the four standard wire types (varint, fixed32, fixed64, bytes). Wire types outside this set (e.g. start/end group, types 3,4,6,7) cannot be safely skipped, so the library aborts with this error instead of attempting to Unmarshal corrupt or non-protobuf bytes.

Source

Thrown at lib/util.go:452

			if offset+8 > len(b) {
				return fmt.Errorf("truncated fixed64 field")
			}
			offset += 8
		case protowire.BytesType:
			l, n := protowire.ConsumeVarint(b[offset:])
			if n < 0 {
				return fmt.Errorf("invalid length-delimited size at offset %d", offset)
			}
			offset += n
			if l > protoMaxFieldBytes {
				return fmt.Errorf("length-delimited field exceeds max size: %d > %d", l, protoMaxFieldBytes)
			}
			if l < 0 || offset+int(l) > len(b) {
				return fmt.Errorf("length-delimited field exceeds buffer bounds")
			}
			offset += int(l)
		default:
			return fmt.Errorf("unsupported wire type %d", wireType)
		}
	}
	return nil
}

// MarshalJSON() serializes a message into a JSON byte slice
func MarshalJSON(message any) ([]byte, ErrorI) {
	// convert the message to json bytes
	jsonBytes, err := json.Marshal(message)
	// if an error occurred during the conversion
	if err != nil {
		// exit with wrapped error
		return nil, ErrJSONMarshal(err)
	}
	// exit with json bytes
	return jsonBytes, nil
}

View on GitHub (pinned to ee8197d91d)

Solutions

  1. Verify the byte source: confirm the bytes were produced by this library's Marshal (protobuf) and not truncated or altered in transit
  2. Check protocol/schema version compatibility between producer and consumer nodes
  3. Log the offending payload (hex) and locate the offset where the unknown wire type appears to identify corruption
  4. If the payload comes from an external peer, reject/drop the connection as the peer is sending malformed data

Example fix

// before: decoding bytes assumed to be protobuf but actually JSON/hex
var msg SomeMsg
lib.Unmarshal(rawStringBytes, &msg)
// after: validate the source format first
if raw[0] != '{' {
    if err := lib.Unmarshal(raw, &msg); err != nil { return err }
} else {
    return fmt.Errorf("expected protobuf bytes, got JSON")
}
Defensive patterns

Strategy: validation

Validate before calling

func looksLikeProto(b []byte) bool {
    if len(b) == 0 { return false }
    // field tag varint: lowest 3 bits are wire type (0,1,2,5 are supported)
    wireType := b[0] & 0x07
    return wireType == 0 || wireType == 1 || wireType == 2 || wireType == 5
}
if !looksLikeProto(raw) { return fmt.Errorf("payload is not protobuf") }

Type guard

func isProtoWireType(wt uint8) bool {
    switch wt { case 0, 1, 2, 5: return true }; return false
}

Try / catch

var msg pb.Message
if err := lib.Unmarshal(raw, &msg); err != nil {
    if strings.Contains(err.Error(), "unsupported wire type") || strings.Contains(err.Error(), "invalid protobuf tag") {
        return ErrMalformedPeerPayload // drop/reject payload
    }
    return err
}

Prevention

When it happens

Trigger: Calling lib.Unmarshal (directly or via any message FromBytes path) with a byte slice that is not valid protobuf for this schema — e.g. random/corrupt bytes, bytes from a different message type, or a hand-crafted payload using group wire types.

Common situations: Peer or RPC payloads corrupted in transit, deserializing a payload produced by an incompatible protocol version, feeding non-protobuf data (JSON, hex) into a protobuf decode path, or fuzzing/malicious input.

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/5317e1dcff7d9c55. Report an issue: GitHub.