gravitational/teleport · error

proto: wrong wireType = %d for field ExistingMFAResponse

Error message

proto: wrong wireType = %d for field ExistingMFAResponse

What it means

Field 1 of CreatePrivilegeTokenRequest is ExistingMFAResponse, an embedded message that must be encoded as length-delimited (wire type 2). The payload presents tag 1 with a different wire type, so the generated Unmarshal returns this error. It indicates encoder/decoder schema mismatch or malformed input.

Source

Thrown at api/client/proto/authservice.pb.go:60426

			b := dAtA[iNdEx]
			iNdEx++
			wire |= uint64(b&0x7F) << shift
			if b < 0x80 {
				break
			}
		}
		fieldNum := int32(wire >> 3)
		wireType := int(wire & 0x7)
		if wireType == 4 {
			return fmt.Errorf("proto: CreatePrivilegeTokenRequest: wiretype end group for non-group")
		}
		if fieldNum <= 0 {
			return fmt.Errorf("proto: CreatePrivilegeTokenRequest: illegal tag %d (wire type %d)", fieldNum, wire)
		}
		switch fieldNum {
		case 1:
			if wireType != 2 {
				return fmt.Errorf("proto: wrong wireType = %d for field ExistingMFAResponse", wireType)
			}
			var msglen int
			for shift := uint(0); ; shift += 7 {
				if shift >= 64 {
					return ErrIntOverflowAuthservice
				}
				if iNdEx >= l {
					return io.ErrUnexpectedEOF
				}
				b := dAtA[iNdEx]
				iNdEx++
				msglen |= int(b&0x7F) << shift
				if b < 0x80 {
					break
				}
			}
			if msglen < 0 {
				return ErrInvalidLengthAuthservice

View on GitHub (pinned to 1283425b60)

Solutions

  1. Match api/client/proto versions on both peers (same field 1 type/numbering)
  2. Build the request via the typed struct and proto.Marshal, never manual bytes
  3. Inspect tag 1 with protoc --decode_raw to confirm the mismatch
  4. Regenerate the pb.go files from the current .proto if the repo was patched inconsistently

Example fix

// before: hand-crafted request bytes
raw := []byte{0x08, 0x01} // field 1 as varint
// after
req := &proto.CreatePrivilegeTokenRequest{ExistingMFAResponse: mfaResp}
raw, err := proto.Marshal(req)
Defensive patterns

Strategy: try-catch

Validate before calling

func field1IsLengthDelimited(b []byte) bool {
    if len(b) == 0 { return false }
    tag, n := binary.Uvarint(b)
    return n > 0 && tag>>3 == 1 && tag&0x7 == 2
}

Type guard

func isWireTypeMismatch(err error) bool {
    return err != nil && strings.Contains(err.Error(), "wrong wireType = ")
}

Try / catch

req := &proto.CreatePrivilegeTokenRequest{}
if err := proto.Unmarshal(blob, req); err != nil {
    if isWireTypeMismatch(err) {
        return trace.AccessDenied("MFA payload from incompatible client version; upgrade client")
    }
    return trace.Wrap(err)
}

Prevention

When it happens

Trigger: Bytes where tag 1 of CreatePrivilegeTokenRequest carries a non-length-delimited wire type — e.g. an encoder treating ExistingMFAResponse as bytes/varint, or an older schema where field 1 was a scalar — during privilege-token creation RPCs with MFA.

Common situations: Version skew between client and auth server around MFA privilege token APIs; custom scripts crafting the request by hand; corrupted frames; decoding a different message's bytes as CreatePrivilegeTokenRequest.

Related errors


AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02). Data as JSON: /api/errors/15c8885c18995e8d. Report an issue: GitHub.