grpc/grpc-go · error
invalid gRPC request method %q
Error message
invalid gRPC request method %q
What it means
Returned by NewServerHandlerTransport when an incoming HTTP request uses any method other than POST. The gRPC over HTTP/2 wire protocol requires POST for all RPCs; the handler writes a 405 Method Not Allowed and returns this error. The check lives at internal/transport/handler_server.go:54-58.
Source
Thrown at internal/transport/handler_server.go:58
"google.golang.org/grpc/internal/grpclog"
"google.golang.org/grpc/internal/grpcutil"
"google.golang.org/grpc/mem"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/peer"
"google.golang.org/grpc/stats"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)
// NewServerHandlerTransport returns a ServerTransport handling gRPC from
// inside an http.Handler, or writes an HTTP error to w and returns an error.
// It requires that the http Server supports HTTP/2.
func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats stats.Handler, bufferPool mem.BufferPool) (ServerTransport, error) {
if r.Method != http.MethodPost {
w.Header().Set("Allow", http.MethodPost)
msg := fmt.Sprintf("invalid gRPC request method %q", r.Method)
http.Error(w, msg, http.StatusMethodNotAllowed)
return nil, errors.New(msg)
}
contentType := r.Header.Get("Content-Type")
// TODO: do we assume contentType is lowercase? we did before
contentSubtype, validContentType := grpcutil.ContentSubtype(contentType)
if !validContentType {
msg := fmt.Sprintf("invalid gRPC request content-type %q", contentType)
http.Error(w, msg, http.StatusUnsupportedMediaType)
return nil, errors.New(msg)
}
if r.ProtoMajor != 2 {
msg := "gRPC requires HTTP/2"
http.Error(w, msg, http.StatusHTTPVersionNotSupported)
return nil, errors.New(msg)
}
if _, ok := w.(http.Flusher); !ok {
msg := "gRPC requires a ResponseWriter supporting http.Flusher"
http.Error(w, msg, http.StatusInternalServerError)
return nil, errors.New(msg)View on GitHub (pinned to 03255a9237)
Solutions
- Ensure only POST requests reach the gRPC handler; reject/redirect other methods at the proxy or router layer.
- For health checks, point them at a dedicated HTTP health endpoint instead of the gRPC service path.
- Handle CORS preflight (OPTIONS) in middleware before the request reaches grpc.Server.ServeHTTP.
- If serving gRPC and REST on the same mux, route by method and content-type to the correct handler.
Example fix
// before
http.Handle("/helloworld.Greeter/", grpcServer)
// a GET to that path yields 405 + the error
// after
mux := http.NewServeMux()
mux.HandleFunc("/healthz", healthHandler) // GET health checks land here
mux.Handle("/helloworld.Greeter/", grpcServer) // only POST gRPC here Defensive patterns
Strategy: validation
Validate before calling
if r.Method != http.MethodPost {
http.Error(w, "use POST", http.StatusMethodNotAllowed)
return
}
srv.ServeHTTP(w, r) Try / catch
if _, err := transport.NewServerHandlerTransport(w, r, stats, pool); err != nil {
// already wrote the HTTP error; just log
log.Printf("non-gRPC request rejected: %v", err)
} Prevention
- Route health checks and non-POST traffic to separate HTTP handlers.
- Handle OPTIONS/CORS preflight before delegating to grpc.Server.ServeHTTP.
- Configure ingress/proxy to only forward POST to gRPC paths.
When it happens
Trigger: Routing a non-POST request (GET, PUT, OPTIONS, HEAD) into grpc.Server.ServeHTTP via the http.Handler transport; a health-check or browser preflight hitting the gRPC endpoint; a reverse proxy forwarding the wrong method.
Common situations: Load balancer health checks using GET against the gRPC path; CORS preflight (OPTIONS) reaching the handler; curl without -X POST; misconfigured gateway that rewrites the method.
Related errors
- invalid gRPC request content-type %q
- token file access error
- empty token_exchange_service_uri in options
- required field SubjectTokenPath is not specified
- required field SubjectTokenType is not specified
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/af5d997fb911117c.
Report an issue: GitHub.