# gRPC over HTTP2 ## Introduction This document serves as a detailed description for an implementation of gRPC carried over HTTP2 framing. It assumes familiarity with the HTTP2 specification. ## Protocol Production rules are using ABNF syntax. ### Outline The following is the general sequence of message atoms in a GRPC request & response message stream * Request → Request-Headers *Length-Prefixed-Message EOS * Response → (Response-Headers *Length-Prefixed-Message Trailers) / Trailers-Only ### Requests * Request → Request-Headers *Length-Prefixed-Message EOS Request-Headers are delivered as HTTP2 headers in HEADERS + CONTINUATION frames. * **Request-Headers** → Call-Definition *Custom-Metadata * **Call-Definition** → Method Scheme Path [Authority] TE [Timeout] Content-Type [Message-Type] [Message-Encoding] [Message-Accept-Encoding] [User-Agent] * **Method** → ":method POST" * **Scheme** → ":scheme " ("http" / "https") * **Path** → ":path" "/" Service-Name "/" {method name} * **Service-Name** → {IDL-specific service name} * **Authority** → ":authority" {virtual host name of authority} * **TE** → "te" "trailers" * **Timeout** → "grpc-timeout" TimeoutValue TimeoutUnit * **TimeoutValue** → {positive integer as ASCII string of at most 8 digits} * **TimeoutUnit** → Hour / Minute / Second / Millisecond / Microsecond / Nanosecond * **Content-Type** → "content-type" "application/grpc" [("+proto" / "+json" / {custom})] * **Content-Coding** → "identity" / "gzip" / "deflate" / "snappy" / {custom} * **Message-Encoding** → "grpc-encoding" Content-Coding * **Message-Accept-Encoding** → "grpc-accept-encoding" Content-Coding *("," Content-Coding) * **User-Agent** → "user-agent" {structured user-agent string} * **Message-Type** → "grpc-message-type" {type name for message schema} * **Custom-Metadata** → Binary-Header / ASCII-Header * **Binary-Header** → {Header-Name "-bin" } {base64 encoded value} * **ASCII-Header** → Header-Name ASCII-Value * **Header-Name** → 1*( %x30-39 / %x61-7A / "_" / "-" / ".") * **ASCII-Value** → 1*( %x20-%x7E ) HTTP2 requires that reserved headers, ones starting with ":" appear before all other headers. Additionally implementations should send **Timeout** immediately after the reserved headers and they should send the **Call-Definition** headers before sending **Custom-Metadata**. If **Timeout** is omitted a server should assume an infinite timeout. Client implementations are free to send a default minimum timeout based on their deployment requirements. If **Content-Type** does not begin with "application/grpc", gRPC servers SHOULD respond with HTTP status of 415 (Unsupported Media Type). **Custom-Metadata** is an arbitrary set of key-value pairs defined by the application layer. Header names starting with "grpc-" but not listed here are reserved for future GRPC use and should not be used by applications as **Custom-Metadata**. Binary header values must be encoded using Base64 as per https://tools.ietf.org/html/rfc4648#section-4. Implementations MUST accept padded and un-padded values and should emit un-padded values. ### Responses * **Response** → (Response-Headers *Length-Prefixed-Message Trailers) / Trailers-Only * **Response-Headers** → HTTP-Status [Message-Encoding] [Message-Accept-Encoding] Content-Type *Custom-Metadata * **Trailers-Only** → HTTP-Status Content-Type Trailers * **Trailers** → Status [Status-Message] [Status-Details] *Custom-Metadata * **HTTP-Status** → ":status 200" * **Status** → "grpc-status" 1*DIGIT * **Status-Message** → "grpc-message" Percent-Encoded * **Status-Details** → "grpc-status-details-bin" {base64 encoded value} * **Percent-Encoded** → 1*(Percent-Byte-Unencoded / Percent-Byte-Encoded) * **Percent-Byte-Unencoded** → 1*( %x20-%x24 / %x26-%x7E ) * **Percent-Byte-Encoded** → "%" 2HEXDIGIT **Response-Headers** & **Trailers-Only** are each delivered in a single HTTP2 HEADERS frame block. Status must be sent in **Trailers** even if the status code is OK. #### HTTP2 Transport Mapping ##### Stream Identification All GRPC calls need to specify an internal ID. HTTP2 stream-ids are used as call identifiers. ##### Errors The following mapping from RST_STREAM error codes to GRPC error codes is applied: HTTP2 Code|GRPC Code ----------|----------- NO_ERROR(0)|INTERNAL PROTOCOL_ERROR(1)|INTERNAL INTERNAL_ERROR(2)|INTERNAL FLOW_CONTROL_ERROR(3)|INTERNAL SETTINGS_TIMEOUT(4)|INTERNAL REFUSED_STREAM|UNAVAILABLE CANCEL(8)|Mapped to call cancellation when sent by a client. CANCELLED when sent by a server. COMPRESSION_ERROR|INTERNAL CONNECT_ERROR|INTERNAL ENHANCE_YOUR_CALM|RESOURCE_EXHAUSTED INADEQUATE_SECURITY|PERMISSION_DENIED ##### Security The HTTP2 specification mandates the use of TLS 1.2 or higher when TLS is used with HTTP2. ##### Connection Management ###### GOAWAY Frame Sent by servers to clients to indicate that they will no longer accept any new streams on the associated connections. ###### PING Frame Both clients and servers can send a PING frame that the peer must respond to by precisely echoing what they received. ### Appendix A - GRPC for Protobuf * **Service-Name** → ?( {proto package name} "." ) {service name} * **Message-Type** → {fully qualified proto message name} * **Content-Type** → "application/grpc+proto" * **Status-Details** → {google.rpc.Status proto message} --- Source: https://raw.githubusercontent.com/grpc/grpc/master/doc/PROTOCOL-HTTP2.md Downloaded: 2026-06-07