how to configure ingress to direct traffic to an https backend using https
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Sending traffic from an Ingress controller to an HTTPS backend is usually a re-encryption configuration, not just a normal route rule. The exact YAML depends on the controller, but the core idea is always the same: terminate or accept TLS at the edge, then tell the controller to use HTTPS when proxying to the service.
Understand the Three Common TLS Patterns
Before writing YAML, decide which pattern you actually want:
- TLS termination at the ingress, then HTTP to the backend.
- TLS termination at the ingress, then HTTPS to the backend.
- TLS passthrough all the way to the backend.
This article is about the second case. The ingress still proxies the request, but it speaks HTTPS to the service behind it.
That is different from pure passthrough, where the ingress does not terminate TLS for normal HTTP routing logic.
NGINX Ingress Re-Encryption Example
With the NGINX ingress controller, the key annotation is usually:
Example:
And the service should target the pod port that actually serves HTTPS.
Without the backend-protocol annotation, the ingress controller may still try plain HTTP to the service and fail with TLS handshake or upstream protocol errors.
When You Need TLS Passthrough Instead
If the backend must receive the original TLS session and do its own certificate handling, you may need TLS passthrough rather than re-encryption.
For NGINX ingress, passthrough is a different mode and typically uses:
But this comes with tradeoffs:
- fewer HTTP-layer routing features
- different controller requirements
- less visibility into HTTP details at the ingress layer
Use passthrough only when you specifically need end-to-end TLS termination at the application.
Backend Certificates and Trust
If the backend serves HTTPS with a self-signed or internal certificate, the ingress controller may not trust it by default. In that case, routing fails even though the annotation is correct.
Controller-specific trust configuration may be required, such as:
- mounting a CA bundle
- configuring proxy SSL trust settings
- using a controller-specific secret annotation
Do not assume "backend uses HTTPS" is enough. The ingress must also trust the backend certificate chain if certificate validation is enabled.
Common Failure Symptoms
Misconfiguration usually shows up as:
- '
502 Bad Gateway' - upstream TLS handshake failures
- backend connection reset errors
- requests hanging because the controller and backend disagree on protocol
The two fastest checks are:
- verify the service port actually serves HTTPS
- verify the ingress annotation matches the controller you use
A useful pod-level test:
If that fails from inside the cluster, the backend is not ready for HTTPS traffic regardless of the ingress config.
Controller-Specific Behavior Matters
Do not copy annotations blindly between ingress controllers. NGINX, Traefik, HAProxy, AWS Load Balancer Controller, and others use different configuration models.
The generic Kubernetes Ingress resource does not define "HTTPS to backend" as a universal field. That behavior is usually implemented through controller-specific annotations or custom resources.
So the reliable approach is:
- identify the ingress controller
- use the controller's documented annotation or CRD
- test inside the cluster and through the ingress endpoint
Common Pitfalls
- Assuming TLS at the ingress automatically means TLS to the backend.
- Using the wrong annotation for the installed ingress controller.
- Pointing the ingress at a service port that actually serves plain HTTP.
- Confusing re-encryption with TLS passthrough.
- Forgetting backend certificate trust requirements for internal or self-signed certs.
Summary
- HTTPS to the backend is usually configured as ingress re-encryption.
- For NGINX ingress, the usual key is
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS". - Make sure the service port really serves HTTPS, not plain HTTP.
- Use TLS passthrough only when you need the backend to terminate the original TLS session.
- Always validate the setup from inside the cluster as well as through the external ingress hostname.

