nats-io/nats-server · error

unsupported type: %d

Error message

unsupported type: %d

What it means

In the protobuf wire-format scanner (server/proto.go), protoScanFieldValue switches on the field's wire type: 0 varint, 1 fixed64, 2 length-delimited, 5 fixed32. Any other wire type is invalid/unknown in the proto spec, so scanning returns this error.

Source

Thrown at server/proto.go:78

func protoScanFieldValue(typ int, b []byte) (size int, err error) {
	switch typ {
	case 0:
		_, size, err = protoScanVarint(b)
	case 5: // fixed32
		if len(b) < 4 {
			return 0, errProtoInsufficient
		}
		size = 4
	case 1: // fixed64
		if len(b) < 8 {
			return 0, errProtoInsufficient
		}
		size = 8
	case 2: // length-delimited
		size, err = protoScanBytes(b)
	default:
		return 0, fmt.Errorf("unsupported type: %d", typ)
	}
	return size, err
}

func protoScanVarint(b []byte) (v uint64, size int, err error) {
	var y uint64
	if len(b) <= 0 {
		return 0, 0, errProtoInsufficient
	}
	v = uint64(b[0])
	if v < 0x80 {
		return v, 1, nil
	}
	v -= 0x80

	if len(b) <= 1 {
		return 0, 0, errProtoInsufficient
	}

View on GitHub (pinned to 3a66a489d2)

Solutions

  1. Verify the sender encodes standard protobuf wire types (0,1,2,5) only.
  2. Re-encode the message with a maintained protobuf library instead of hand-rolling bytes.
  3. Check for corruption/truncation in transport between peers.
  4. If encountered in fuzzing, treat as expected invalid input and discard.

Example fix

// before: field tag uses wire type 3 (group)
tag = (fieldNum << 3) | 3
// after: use length-delimited
tag = (fieldNum << 3) | 2
Defensive patterns

Strategy: validation

Validate before calling

// Validate wire type before scanning a protobuf field
typ := int(tag & 0x7)
if typ != 0 && typ != 1 && typ != 2 && typ != 5 {
    return errors.New("invalid protobuf wire type")
}

Type guard

func wireTypeSupported(typ int) bool {
    switch typ {
    case 0, 1, 2, 5:
        return true
    }
    return false
}

Try / catch

size, err := protoScanFieldValue(b, typ)
if err != nil {
    return fmt.Errorf("corrupt protobuf field (wire type %d): %w", typ, err)
}

Prevention

When it happens

Trigger: protoScanField (called during protobuf message scanning) encounters a field header whose wire-type nibble is 3, 4, 6, or 7 (e.g. legacy group types 3/4 or corrupt data).

Common situations: Corrupted or truncated protobuf payloads, hand-crafted byte slices in tests/fuzzing, or a peer sending a message encoded with deprecated group wire types.

Related errors


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/55b8258a14152b0e. Report an issue: GitHub.