grpc/grpc-go · warning
invalid gRPC request content-type
Error message
invalid gRPC request content-type %q
What it means
Returned by NewServerHandlerTransport when the Content-Type header is not a valid gRPC content type. gRPC requires Content-Type to start with 'application/grpc' (optionally followed by '+subtype' or ';subtype'). If the header is missing, empty, or any other value, the request is rejected with HTTP 415 Unsupported Media Type.
Solutions
- Ensure the client sends 'Content-Type: application/grpc' (or 'application/grpc+proto').
- If serving gRPC-Web, ensure the transcoding proxy sets the correct content type.
- Separate HTTP/JSON endpoints from gRPC endpoints in your routing.
- Check that proxies and CDNs preserve the Content-Type header.
Example fix
// before: missing content-type curl -X POST http://localhost:8080/myapp.Service/Method // after: include gRPC content-type curl -X POST -H "Content-Type: application/grpc" \ http://localhost:8080/myapp.Service/Method
Defensive patterns
Strategy: validation
Validate before calling
// Ensure requests to the gRPC endpoint have the correct content-type.
// In a reverse proxy, validate and set Content-Type.
if !strings.HasPrefix(r.Header.Get("Content-Type"), "application/grpc") {
http.Error(w, "gRPC requires application/grpc content-type", 415)
return
} Try / catch
st, err := transport.NewServerHandlerTransport(w, r, stats, pool)
if err != nil {
// HTTP error already written; log and return
log.Printf("gRPC transport rejected request: %v", err)
return
} Prevention
- Ensure all gRPC clients send 'Content-Type: application/grpc'.
- Verify proxies and CDNs preserve the Content-Type header.
- Separate gRPC endpoints from HTTP/JSON endpoints.
- Use gRPC-Web transcoding proxies that set the correct content type.
When it happens
Trigger: An HTTP request to the gRPC handler transport without a Content-Type header, or with a non-gRPC content type like 'application/json' or 'text/plain'. The check via grpcutil.ContentSubtype at handler_server.go:62-66 returns false.
Common situations: Non-gRPC HTTP client hitting the gRPC endpoint; a gRPC-Web proxy that strips or doesn't set Content-Type; curl without the -H content-type flag; browser preflight or direct fetch without gRPC framing; service mesh or CDN stripping content-type headers.
Related errors
- gRPC requires a ResponseWriter supporting http.Flusher
- invalid gRPC request method
- gRPC requires HTTP/2
- transport: set send compressor called after headers sent or…
- buffer size is not an exponent of two
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/4b387ba61b056b17.
Report an issue: GitHub.
Appendix: source
Thrown at internal/transport/handler_server.go:66
)
// 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)
}
var localAddr net.Addr
if la := r.Context().Value(http.LocalAddrContextKey); la != nil {
localAddr, _ = la.(net.Addr)
}
var authInfo credentials.AuthInfo
if r.TLS != nil {View on GitHub (pinned to 0c51461d27)