{"record":{"id":"45655b4eba47ac19","repo":"grpc/grpc-go","slug":"grpc-requires-http-2","errorCode":null,"errorMessage":"gRPC requires HTTP/2","messagePattern":"gRPC requires HTTP/2","errorType":"http","errorClass":null,"httpStatus":505,"severity":"error","filePath":"internal/transport/handler_server.go","lineNumber":70,"sourceCode":"// 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 {\n\t\tauthInfo = credentials.TLSInfo{State: *r.TLS, CommonAuthInfo: credentials.CommonAuthInfo{SecurityLevel: credentials.PrivacyAndIntegrity}}\n\t}\n\tp := peer.Peer{\n\t\tAddr:      strAddr(r.RemoteAddr),","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/internal/transport/handler_server.go#L52-L88","documentation":"gRPC requires HTTP/2. NewServerHandlerTransport checks r.ProtoMajor == 2 and returns HTTP 505 HTTP Version Not Supported for any HTTP/1.x request. The underlying http.Server must be configured to negotiate HTTP/2.","triggerScenarios":"An HTTP/1.1 client (plain curl without --http2, an HTTP/1.1-only proxy, or a browser/proxy that failed h2 negotiation) reaches the gRPC handler transport.","commonSituations":"A reverse proxy terminating TLS and forwarding to the backend over HTTP/1.1 instead of h2/h2c; a load balancer without h2 support; plaintext HTTP/1.1 health probes; missing http2.Enable in Go's http.Server.","solutions":["Ensure the upstream hop to the gRPC server speaks HTTP/2 (h2 over TLS, or h2c for plaintext).","Configure the reverse proxy to negotiate h2 with the backend (e.g. Traefik/Envoy/Nginx h2 upstream).","For plaintext Go servers, use h2c via golang.org/x/net/http2/h2c.","Use a gRPC-aware client that defaults to HTTP/2."],"exampleFix":"// before: HTTP/1.1-only server\n//   srv := &http.Server{Addr: \":80\", Handler: grpcServer}\n//   srv.ListenAndServe()\n//\n// after: h2c server so plaintext HTTP/2 works\n//   h2s := &http2.Server{}\n//   handler := h2c.NewHandler(grpcServer, h2s)\n//   srv := &http.Server{Addr: \":80\", Handler: handler}\n//   srv.ListenAndServe()","handlingStrategy":"validation","validationCode":"// Reject non-h2 requests early, before the gRPC transport sees them.\nfunc requireHTTP2(next http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tif r.ProtoMajor != 2 {\n\t\t\thttp.Error(w, \"gRPC requires HTTP/2\", http.StatusHTTPVersionNotSupported)\n\t\t\treturn\n\t\t}\n\t\tnext.ServeHTTP(w, r)\n\t})\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Serve gRPC over h2 (TLS) or h2c (plaintext) using golang.org/x/net/http2/h2c.","Configure reverse proxies to use an HTTP/2 upstream.","Use gRPC client libraries, which negotiate HTTP/2 by default."],"tags":["grpc","transport","http2","handler-server","network"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}