Upstream by hostname proxy pass

My issue:
When proxying via the upstream module, the Host header is replaced with the upstream name or the name of the server itself.

How I encountered the problem:

Update nginx from version 1.18.0 to version 1.28.2

Solutions I’ve tried:
map, separate server sections

Version of NGINX or NGINX adjacent software (e.g. NGINX Gateway Fabric):
1.28.2

Deployment environment:

upstream backends {
server kc1.dc1;
server kc1.dc2;
}

server {
listen 443 ssl;
listen [::]:443 ssl;

server_name kc-proxy.nextcomdev.xyz 

ssl_certificate /etc/nginx/ssl/nextcomdev.ru.crt; 
ssl_certificate_key /etc/nginx/ssl/nextcomdev.ru.key; 
ssl_dhparam /etc/nginx/ssl/dhparam.pem; 

location /openid/ciba/callback { 
  proxy_pass https://backends; 

  proxy_set_header Host $http_host; 
  proxy_set_header Connection ""; 

  proxy_next_upstream error timeout http_403 http_404 http_429 http_500 http_502 http_503 http_504; 

  proxy_next_upstream_tries 3; 
  proxy_next_upstream_timeout 10s; 

  proxy_connect_timeout 3s; 
  proxy_read_timeout    5s; 
  proxy_send_timeout    5s; 

  proxy_ssl_verify              off; 
} 

location / { 
  return 204; 
} 

}

NGINX access/error log:
2026/02/28 11:20:37 [error] 1009539#1009539: *94282 no live upstreams while connecting to upstream, client: 1.1.1.1, server: kc-proxy.nextcomdev.xyz, request: “GET /openid/ciba/callback HTTP/1.1”, upstream: "
https://backends/openid/ciba/callback ", host: “kc-proxy.nextcomdev.xyz”

1 Like

The primary problem with your configuration is that you are using proxy_pass https://… (with TLS) but the server directives in the upstream block do not specify a port. Therefore port 80 is assumed. That’s why the error log says “no live upstreams” because the upstream module is trying to reach https://kc1.dc1:80/

See Module ngx_http_upstream_module

A secondary problem is more closely related to the title. It is more reliable to use the $host variable instead of $http_host because if the client does not send the Host header then the name of the upstream block will be used instead.

See Module ngx_http_proxy_module

2 Likes

If specify the port and host header. I see a mistake:
no live upstreams while connecting to upstream: "https://backends

For some reason, the upstream name is used and not the destination host name.

1 Like