thanos-io/thanos · error

proto: unexpected end of group

Error message

proto: unexpected end of group

What it means

ErrUnexpectedEndOfGroupRpc is a gogo-protobuf generated sentinel returned when parsing an unknown/legacy group wire type: an end-of-group tag (wire type 4) arrives when no group is open (depth == 0), meaning the byte stream ends a group that was never started. The data is structurally invalid protobuf.

Solutions

  1. Confirm reads are not truncated (check io.ReadFull / buffer bounds upstream).
  2. Avoid proto2 groups; regenerate schema with message types instead.
  3. Verify message framing (length-delimited) when concatenating multiple messages in one buffer.
  4. Treat as corrupt input and surface a deserialization error to the caller.

Example fix

// before
msg := &exemplarspb.Exemplars{}
if err := proto.Unmarshal(buf, msg); err != nil { return err }
// after
if err := proto.Unmarshal(buf, msg); err != nil {
    return errors.Wrap(err, "failed to decode exemplars: input may be truncated or corrupt")
}
Defensive patterns

Strategy: try-catch

Validate before calling

if len(data) == 0 { return errors.New("empty protobuf payload") }

Try / catch

if err := proto.Unmarshal(data, msg); err != nil {
    if errors.Is(err, ErrUnexpectedEndOfGroupRpc) { return errors.Wrap(err, "truncated or misframed protobuf message") }
    return err
}

Prevention

When it happens

Trigger: Unmarshaling bytes containing a group-end tag without a matching group-start tag, e.g. from truncated or concatenated messages in exemplarspb/statuspb decoding paths.

Common situations: Truncated network reads, offset miscalculation when reading messages from packed files or buckets, or legacy proto2 group fields misinterpreted by proto3 code.

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 thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/c3f9cd925e56d488. Report an issue: GitHub.

Appendix: source

Thrown at pkg/status/statuspb/rpc.pb.go:2006

		case 5:
			iNdEx += 4
		default:
			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
		}
		if iNdEx < 0 {
			return 0, ErrInvalidLengthRpc
		}
		if depth == 0 {
			return iNdEx, nil
		}
	}
	return 0, io.ErrUnexpectedEOF
}

var (
	ErrInvalidLengthRpc        = fmt.Errorf("proto: negative length found during unmarshaling")
	ErrIntOverflowRpc          = fmt.Errorf("proto: integer overflow")
	ErrUnexpectedEndOfGroupRpc = fmt.Errorf("proto: unexpected end of group")
)

View on GitHub (pinned to 35b8b99117)