gravitational/teleport · error
proto: CreateRegisterChallengeRequest: wiretype end group fo
Error message
proto: CreateRegisterChallengeRequest: wiretype end group for non-group
What it means
The generated Unmarshal for CreateRegisterChallengeRequest encountered an END_GROUP wire type (4) with no preceding START_GROUP. Since this message schema contains no groups, such bytes are structurally invalid and decoding aborts. This is generated-code protection against corrupt or mismatched wire data.
Source
Thrown at api/client/proto/authservice.pb.go:60505
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAuthservice
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
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: CreateRegisterChallengeRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: CreateRegisterChallengeRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field TokenID", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowAuthservice
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]View on GitHub (pinned to 1283425b60)
Solutions
- Ensure Unmarshal receives exactly one complete message starting at byte 0 of the buffer
- Use proper gRPC framing instead of manual stream slicing
- Verify both endpoints run matching generated proto code
- Re-produce the payload with proto.Marshal to replace suspect bytes
Example fix
// before: wrong offset into a framed stream err := proto.Unmarshal(buf[3:], req) // after: frame with length prefixes msgLen, n := binary.Uvarint(hdr) err = proto.Unmarshal(buf[n:n+int(msgLen)], req)
Defensive patterns
Strategy: validation
Validate before calling
func alignedMessageBoundary(b []byte) error {
if len(b) == 0 { return errors.New("empty payload") }
tag, n := binary.Uvarint(b)
if n <= 0 { return errors.New("cannot decode leading tag: not at a message boundary") }
if tag&0x7 == 4 { return errors.New("payload starts with END_GROUP; misaligned") }
return nil
} Type guard
func isEndGroupError(err error) bool {
return err != nil && strings.Contains(err.Error(), "end group for non-group")
} Try / catch
if err := proto.Unmarshal(buf, req); err != nil {
if isEndGroupError(err) {
return trace.BadParameter("stream framing desync detected; reset connection")
}
return trace.Wrap(err)
} Prevention
- Never slice into a stream at arbitrary offsets; use length-prefix framing
- Reset the stream/connection after any decode error to avoid desync cascades
- Ensure proxies preserve gRPC framing bytes untouched
- Fuzz decoders with stray group tags in CI
When it happens
Trigger: Passing bytes containing a stray wire-type-4 tag to CreateRegisterChallengeRequest Unmarshal — from stream desync, corrupted frames, or a nonstandard encoder emitting proto2 group markers.
Common situations: Reading a payload from the middle of a multiplexed stream; truncated/reassembled TCP frames; fuzz testing; decoding another message type's serialized bytes as this request.
Related errors
- proto: CreatePrivilegeTokenRequest: wiretype end group for n
- proto: CreatePrivilegeTokenRequest: illegal tag %d (wire typ
- proto: CreateRegisterChallengeRequest: illegal tag %d (wire
- proto: Passwordless: wiretype end group for non-group
- proto: Passwordless: illegal tag %d (wire type %d)
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/e04afe13f2f2f62e.
Report an issue: GitHub.