Can Istio Proxy Both REST and gRPC?

Published

  • Istio
  • gRPC
  • Kubernetes
  • Service mesh

Istio can proxy both REST (HTTP) and gRPC. The official documentation explains that Istio proxies all TCP traffic, including HTTP, HTTPS, gRPC and plain TCP. However, to use features such as routing or rich metrics, Istio has to know the protocol, and this post is about whether to let it detect that automatically or to state it yourself. What follows summarizes the official Istio document Protocol Selection (checked on 2026-10-20; the version shown on the document is 1.31.2).

How Istio decides the protocolService port definition → Is there an appProtocol?; Is there an appProtocol? → Follow appProtocol (Yes); Is there an appProtocol? → Is the port name in protocol-suffix form? (No); Is the port name in protocol-suffix form? → Follow the protocol in the name (Yes); Is the port name in protocol-suffix form? → Sidecar auto-detects HTTP/HTTP2, falls back to TCP (No)YesNoYesNoService portdefinitionIs there anappProtocol?Follow appProtocolIs the port name inprotocol-suffixform?Follow the protocolin the nameSidecarauto-detectsHTTP/HTTP2, fallsback to TCP
How Istio decides the protocol — An explicit setting takes priority over automatic detection

How do I tell Istio the protocol?

There are two ways. One is to name the Service port in the form <protocol>[-<suffix>]; the other is to use the appProtocol field on Kubernetes 1.18 or later. If both are set, appProtocol takes priority over the port name.

apiVersion: v1
kind: Service
metadata:
  name: orders
spec:
  ports:
    - name: http-web        # set by name: REST
      port: 80
    - name: grpc-api        # set by name: gRPC
      port: 9090
    - name: backend         # set by appProtocol
      port: 8081
      appProtocol: grpc

In the support table of the official document, grpc and grpc-web are handled the same as http2 by both the sidecar and the gateway. So whether you write grpc or http2 on a gRPC port, it is processed as the same HTTP/2.

Can I leave it to automatic detection?

The sidecar automatically detects HTTP and HTTP/2. If it cannot detect the protocol, it treats that traffic as plain TCP. On a connection that looks like TCP, you cannot use HTTP-level routing and metrics. Also, protocols where the server speaks first (Server First), such as MySQL, do not work with automatic detection, so you must specify them by name. That is why, for services you run, it is safer to name the ports by the convention from the start.

Why look at the gateway separately?

Unlike the sidecar, a gateway does not automatically work out, by default, which kind of HTTP to send to the backend. Without an explicit setting, it forwards every incoming HTTP request as HTTP/1.1. So if the backend is gRPC, you must specify grpc or http2 for it to be forwarded as HTTP/2.

A gRPC service behind a gatewayIf not specified: The gateway forwards as HTTP/1.1, May not match a gRPC backend → Specified as grpc or http2: Forwarded as HTTP/2, The gRPC request arrives as isIf not specifiedThe gatewayforwards asHTTP/1.1May not match agRPC backendSpecified as grpc orhttp2Forwarded asHTTP/2The gRPC requestarrives as is
A gRPC service behind a gateway

Instead of an explicit setting, you can also give the Service the useClientProtocol option. It makes the gateway forward with the same protocol as the incoming request. However, the official document warns that it can be dangerous for a service that does not support HTTP/2. An HTTPS gateway always advertises support for HTTP/1.1 and HTTP/2, so a modern client can choose HTTP/2 even if the backend cannot speak it.

How is this different from a plain Kubernetes Service?

A plain Kubernetes Service balances load at L4 (per connection). gRPC keeps one connection open for a long time and sends many requests over it, so once a connection attaches to one pod, the requests concentrate there as well. Istio’s proxy (Envoy), on the other hand, knows that gRPC is HTTP/2 and can distribute per request. This is the typical reason to put a mesh in front of gRPC services. This part is not from the document page above; it describes the general difference between L4 and L7 balancing, so check the actual distribution in your own environment.

Frequently asked questions

Is UDP also proxied?

No. According to the document, non-TCP protocols such as UDP are not proxied and behave as usual, without being intercepted by the Istio proxy. So you cannot use them in proxy-only components such as ingress or egress gateways either.

If I set both the port name and appProtocol, which one wins?

appProtocol. The port name steps back when both are defined.

For a gRPC port name, which is better, grpc or http2?

The behavior is the same. In the official table grpc is treated the same as http2, so use grpc, which tells the reader right away that it is gRPC.

Shall we build your site?

Get a free consultation