A Real-World Istio Gotcha: HTTPS Proxy and TCP Tunneling

Debugging a 404 error in AKS revealed how Istio handles HTTPS proxy traffic differently than expected. Learn why HTTP CONNECT requires TCP configuration in ServiceEntry and how this fixes external API connectivity.

Madhubanti Jash

4/27/20261 min read

A few days ago, I faced an issue while trying to connect to an external API from a pod in our AKS cluster.

I encountered the following response:

curl -X OPTIONS https://en.wikipedia.org/wiki/Main_Page -I

HTTP/2 404

date: Wed, 24 March 2026 14:00:05 GMT

server: istio-envoy

At first, it wasn’t clear what the issue was. After digging deeper, I understood the root cause.

🔍 What was happening?

  • We were using two proxies:

    • Istio sidecar Envoy proxy

    • An HTTPS proxy configured inside the cluster for external API access

  • All outbound traffic from an Istio-enabled pod is redirected to the sidecar proxy by default

  • Access to external URLs depends on sidecar proxy configuration

🧠 Key realization

  • The traffic flow was:

    • App → Istio sidecar → HTTPS proxy → External API

  • However, Istio didn’t know how to properly handle this proxy connection

⚙️ Solution approach

One solution was to create and configure a ServiceEntry to allow controlled access to external URLs:

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
name: proxy
spec:
hosts:
- my-company-proxy.com # ignored as it will rather check for addresses
addresses:
- $PROXY_IP/32
ports:
- number: $PROXY_PORT
name: tcp
protocol: TCP
location: MESH_EXTERNAL
resolution: NONE
EOF

❓ Why use TCP protocol instead of HTTP?

  • Applications use HTTP CONNECT to establish connections with HTTPS proxies

  • After the connection is established, it becomes a raw TCP tunnel

  • Istio sidecar proxy is designed for HTTP-aware traffic

  • However, HTTP CONNECT switches the connection into a TCP stream

⚠️ What goes wrong with HTTP?

  • If you configure protocol as HTTP:

    • Istio expects HTTP-aware traffic

    • But the actual traffic is raw TCP

  • This mismatch leads to:

    • Routing issues

    • 404 errors

✅ Why TCP works

  • By specifying TCP:

    • You tell Istio to treat traffic as a raw TCP passthrough

    • Istio stops trying to interpret HTTP semantics

  • Essentially:

    • “Don’t inspect this traffic—just forward it”

🌍 Additional config

  • location: MESH_EXTERNAL

    • Indicates that the destination is outside the Istio mesh

🚀 Final result

After applying the configuration:

kubectl exec "$SOURCE_POD" -c curl -- sh -c "HTTPS_PROXY=$PROXY_IP:$PROXY_PORT curl https://en.wikipedia.org/wiki/Main_Page" | grep -o "<title>.*</title>"

Output:

<title>Wikipedia, the free encyclopedia</title>

💡 Key takeaway

  • HTTP CONNECT turns traffic into a TCP tunnel

  • Istio must be configured accordingly

  • Use TCP protocol in ServiceEntry when dealing with HTTPS proxies

📚 References