bigywater.tech
常见报错 · 34

Nginx 502 Bad Gateway:error.log 里 connect() failed、prematurely closed、sent too big header 各是什么故障,上游全挂后恢复要等 fail_timeout

“502 Bad Gateway” 页面上什么原因都没有,真正的线索只在 error.log 里。这篇在本机起一个自己的 nginx 和几个行为不同的上游,把上游没起、崩溃、复位、回非 HTTP、响应头太大这几种情形在 error.log 里的样子逐个对照,并测了多台上游全挂之后的恢复过程。

61
error.log 里 Connection refused 前面的数字(这台 macOS 上的 errno,Linux 上不同)
4 种
实测的 502 日志措辞:connect() failed、prematurely closed、Connection reset by peer、sent too big header
2.5 s
两台上游全挂、fail_timeout=2s 时,其中一台恢复后第一次请求成功的时间(此前都是 no live upstreams)

502 的线索在哪

实测 · 本机执行输出
  客户端:HTTP 502,页面标题 "502 Bad Gateway",Server: nginx/1.31.7
      error.log: [error] *2 kevent() reported that connect() failed (61: Connection refused) while connecting to upstream, request: "GET /refused HTTP/1.1", upstream: "http://127.0.0.1:9791/refused", host: "127.0.0.1:9780"
  同一个请求看 access.log:127.0.0.1 - - [29/Oct/2026:15:12:46 +0800] "GET /refused HTTP/1.1" 502 157 "-" "Python-urllib/3.14"

页面上没有原因,error.log 有;access.log 只记 502。

上游故障的几种样子

实测 · 本机执行输出
  上游收到请求就关闭连接:客户端 HTTP 502
      error.log: [error] *4 upstream prematurely closed connection while reading response header from upstream, request: "GET /close HTTP/1.1", upstream: "http://127.0.0.1:9792/close", host: "127.0.0.1:9780"
  上游发 RST 复位:客户端 HTTP 502
      error.log: [error] *6 kevent() reported about an closed connection (54: Connection reset by peer) while reading response header from upstream, request: "GET /rst HTTP/1.1", upstream: "http://127.0.0.1:9793/rst", host: "127.0.0.1:9780"
  上游回的不是 HTTP:客户端 HTTP None,收到的内容 'BadStatusLine: THIS IS NOT HTTP\r\n'
      error.log: [error] *8 upstream sent no valid HTTP/1.0 header while reading response header from upstream, request: "GET /garbage HTTP/1.1", upstream: "http://127.0.0.1:9794/garbage", host: "127.0.0.1:9780"
  上游响应头 20000 字节:客户端 HTTP 502
      error.log: [error] *10 upstream sent too big header while reading response header from upstream, request: "GET /bighdr HTTP/1.1", upstream: "http://127.0.0.1:9795/bighdr", host: "127.0.0.1:9780"

没起、收到请求就关、复位、响应头太大,日志措辞各不相同;回非 HTTP 内容时客户端甚至不是 502。

谁生成的 502

实测 · 本机执行输出
  上游自己回 502:客户端 HTTP 502,页面内容 "upstream says 502",Server 头 nginx/1.31.7,error.log 里 0 条错误
  nginx 生成的 502:HTTP 502,页面标题 "502 Bad Gateway",Server 头 nginx/1.31.7,error.log 里 1 条错误
  对照,正常上游:HTTP 200 ok

上游自己回的 502 被原样透传、error.log 没记录;Server 头都是 nginx。

常见修法

实测 · 本机执行输出
  nginx -t:nginx: configuration file <tmp>/nginx.conf test is successful
  proxy_buffer_size 32k 之后,上游响应头 20000 字节:HTTP 200 ok
  error_page 502 之后,上游没起:HTTP 502,页面 "服务暂时不可用,请稍后再试"

proxy_buffer_size 调大;error_page 换页面。

多台上游全挂之后

实测 · 本机执行输出
  nginx -t:nginx: configuration file <tmp>/nginx.conf test is successful
  两台都没起,第 1 次请求:HTTP 502(1 ms)
      error.log: [error] *2 kevent() reported that connect() failed (61: Connection refused) while connecting to upstream, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:9798/", h
      error.log: [warn] *2 upstream server temporarily disabled while connecting to upstream, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:9798/", host: "127.0.0.1:9780"
      error.log: [error] *2 kevent() reported that connect() failed (61: Connection refused) while connecting to upstream, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:9799/", h
      error.log: [warn] *2 upstream server temporarily disabled while connecting to upstream, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:9799/", host: "127.0.0.1:9780"
  紧接着第 2 次请求:HTTP 502
      error.log: [error] *5 no live upstreams while connecting to upstream, request: "GET / HTTP/1.1", upstream: "http://pool/", host: "127.0.0.1:9780"
  9798 已恢复。之后每 0.5 s 请求一次(fail_timeout = 2 s),看第几次开始成功:
      恢复后 0.0 s:HTTP 502  error.log: [error] no live upstreams while connecting to upstream, client: 127.0.0.1, server: , reque
      恢复后 0.5 s:HTTP 502  error.log: [error] no live upstreams while connecting to upstream, client: 127.0.0.1, server: , reque
      恢复后 1.0 s:HTTP 502  error.log: [error] no live upstreams while connecting to upstream, client: 127.0.0.1, server: , reque
      恢复后 1.5 s:HTTP 502  error.log: [error] no live upstreams while connecting to upstream, client: 127.0.0.1, server: , reque
      恢复后 2.0 s:HTTP 502  error.log: [error] no live upstreams while connecting to upstream, client: 127.0.0.1, server: , reque
      恢复后 2.5 s:HTTP 200  error.log: [warn] upstream server temporarily disabled while connecting to upstream, client: 127.0.0.

标为暂时不可用,fail_timeout 内直接 502,恢复后也要等。

分步演示

网关错误
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64;报错文本都是真实复现时原样捕获的(命令行工具统一用 LC_ALL=C 取英文原文,路径换成 );所有服务都是本机上自己起的、只监听 127.0.0.1,不访问外网;计时用 time.perf_counter,数字每次运行会有小幅抖动。本篇用 nginx/1.31.7(Homebrew,OpenSSL 4.0.3);每个实验起一个自己的 nginx(自己的前缀目录与配置,只监听 127.0.0.1:9780),上游是 Python 脚本里起的小服务;errno 数字与 kevent() 的措辞是 macOS 上的
    • 没有验证:Linux 上的 error.log 措辞(connect() failed (111: Connection refused)、epoll 相关);SELinux 拦截上游连接(Linux 专有);FastCGI(php-fpm)、uwsgi、gunicorn 作为上游的具体报错;unix socket 上游的权限错误(Permission denied);proxy_next_upstream 对非幂等请求的限制;upstream keepalive 导致的偶发 502;HTTP/2 / gRPC 上游
    京ICP备2026067502号-1京公网安备11010502063487号