grpc-ecosystem/grpc-gateway · error

extension is %T; want an HttpRule

Error message

extension is %T; want an HttpRule

What it means

Type-assertion error in extractAPIOptions: the google.api.http extension present on a MethodOptions did not unmarshal/decode into *options.HttpRule (ext holds some other message type). Since proto.GetExtension returned an unexpected concrete type, the method's HTTP options cannot be read and loadServices fails.

Source

Thrown at internal/descriptor/services.go:224

		if err := applyOpts(opts); err != nil {
			return nil, err
		}
	}

	return meth, nil
}

func extractAPIOptions(meth *descriptorpb.MethodDescriptorProto) (*options.HttpRule, error) {
	if meth.Options == nil {
		return nil, nil
	}
	if !proto.HasExtension(meth.Options, options.E_Http) {
		return nil, nil
	}
	ext := proto.GetExtension(meth.Options, options.E_Http)
	opts, ok := ext.(*options.HttpRule)
	if !ok {
		return nil, fmt.Errorf("extension is %T; want an HttpRule", ext)
	}
	return opts, nil
}

func defaultAPIOptions(svc *Service, md *descriptorpb.MethodDescriptorProto) (*options.HttpRule, error) {
	// FQSN prefixes the service's full name with a '.', e.g.: '.example.ExampleService'
	fqsn := strings.TrimPrefix(svc.FQSN(), ".")

	// This generates an HttpRule that matches the gRPC mapping to HTTP/2 described in
	// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md#requests
	// i.e.:
	//   * method is POST
	//   * path is "/<service name>/<method name>"
	//   * body should contain the serialized request message
	rule := &options.HttpRule{
		Pattern: &options.HttpRule_Post{
			Post: fmt.Sprintf("/%s/%s", fqsn, md.GetName()),
		},

View on GitHub (pinned to a58a4436a3)

Solutions

  1. Regenerate/recompile descriptors so google.api.http is linked to the correct HttpRule type.
  2. Ensure the .proto imports google/api/annotations.proto and the extension value is actually an HttpRule.
  3. Check for descriptor corruption or mismatched protoc/plugin versions.
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at internal/descriptor/services.go:224 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of grpc-ecosystem/grpc-gateway@a58a4436a3 (2026-09-02). Data as JSON: /api/errors/75f01b34670e5d41. Report an issue: GitHub.