{"record":{"id":"4b387ba61b056b17","repo":"grpc/grpc-go","slug":"invalid-grpc-request-content-type-q","errorCode":null,"errorMessage":"invalid gRPC request content-type %q","messagePattern":"invalid gRPC request content-type %q","errorType":"http","errorClass":null,"httpStatus":415,"severity":"warning","filePath":"internal/transport/handler_server.go","lineNumber":66,"sourceCode":")\n\n// NewServerHandlerTransport returns a ServerTransport handling gRPC from\n// inside an http.Handler, or writes an HTTP error to w and returns an error.\n// It requires that the http Server supports HTTP/2.\nfunc NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats stats.Handler, bufferPool mem.BufferPool) (ServerTransport, error) {\n\tif r.Method != http.MethodPost {\n\t\tw.Header().Set(\"Allow\", http.MethodPost)\n\t\tmsg := fmt.Sprintf(\"invalid gRPC request method %q\", r.Method)\n\t\thttp.Error(w, msg, http.StatusMethodNotAllowed)\n\t\treturn nil, errors.New(msg)\n\t}\n\tcontentType := r.Header.Get(\"Content-Type\")\n\t// TODO: do we assume contentType is lowercase? we did before\n\tcontentSubtype, validContentType := grpcutil.ContentSubtype(contentType)\n\tif !validContentType {\n\t\tmsg := fmt.Sprintf(\"invalid gRPC request content-type %q\", contentType)\n\t\thttp.Error(w, msg, http.StatusUnsupportedMediaType)\n\t\treturn nil, errors.New(msg)\n\t}\n\tif r.ProtoMajor != 2 {\n\t\tmsg := \"gRPC requires HTTP/2\"\n\t\thttp.Error(w, msg, http.StatusHTTPVersionNotSupported)\n\t\treturn nil, errors.New(msg)\n\t}\n\tif _, ok := w.(http.Flusher); !ok {\n\t\tmsg := \"gRPC requires a ResponseWriter supporting http.Flusher\"\n\t\thttp.Error(w, msg, http.StatusInternalServerError)\n\t\treturn nil, errors.New(msg)\n\t}\n\n\tvar localAddr net.Addr\n\tif la := r.Context().Value(http.LocalAddrContextKey); la != nil {\n\t\tlocalAddr, _ = la.(net.Addr)\n\t}\n\tvar authInfo credentials.AuthInfo\n\tif r.TLS != nil {","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/transport/handler_server.go#L48-L84","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: missing content-type\ncurl -X POST http://localhost:8080/myapp.Service/Method\n// after: include gRPC content-type\ncurl -X POST -H \"Content-Type: application/grpc\" \\\n  http://localhost:8080/myapp.Service/Method","handlingStrategy":"validation","validationCode":"// Ensure requests to the gRPC endpoint have the correct content-type.\n// In a reverse proxy, validate and set Content-Type.\nif !strings.HasPrefix(r.Header.Get(\"Content-Type\"), \"application/grpc\") {\n    http.Error(w, \"gRPC requires application/grpc content-type\", 415)\n    return\n}","typeGuard":null,"tryCatchPattern":"st, err := transport.NewServerHandlerTransport(w, r, stats, pool)\nif err != nil {\n    // HTTP error already written; log and return\n    log.Printf(\"gRPC transport rejected request: %v\", err)\n    return\n}","preventionTips":["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."],"tags":["transport","http","content-type","handler-server","grpc","validation"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}