proxy_intercept_errors本身不捕获错误,仅作拦截开关,必须与同一location内的error_page成对配置才能生效;它只作用于proxy_pass场景,且要求后端响应体非空、状态码≥400,并配合正确路径的internal location提供降级页。

proxy_intercept_errors 本身不捕获错误,它只是告诉 Nginx “当后端返回 4xx/5xx 响应时,别直接透传,先停一下,等我安排”——真正完成捕获和响应的是它必须搭配的 error_page 指令。
必须在同一 location 中成对配置
单独写 proxy_intercept_errors on; 完全无效。它只在有 proxy_pass 的 location 内起作用,且必须与 error_page 出现在同一作用域:
- 在代理块中启用:`proxy_intercept_errors on;`
- 紧跟着声明要接管的状态码:`error_page 502 504 /fallback.html;`
- 确保该 location 下有对应的
proxy_pass,例如 `proxy_pass http://backend;`
响应体不能为空
Nginx 默认只拦截响应体长度 ≥ 512 字节的错误响应。如果后端返回精简的 502(比如只有 "Bad Gateway" 纯文本),可能被跳过:
- 让后端返回带 HTML body 的错误页(哪怕只是
<p>Service unavailable</p>) - 或在后端响应头中显式设置
Content-Length - 调试时用
curl -i查看真实响应头和 body 长度
降级页路径要能被正确服务
error_page 502 /fallback.html 中的 /fallback.html 是 URI,不是文件路径。Nginx 需要有对应 location 来响应这个请求:
- 推荐写法:
location = /fallback.html { root /usr/share/nginx/html; internal; } -
internal防止用户直接访问该页面 -
root指向实际文件所在目录,即文件物理路径为/usr/share/nginx/html/fallback.html
常见失效原因
配了却还是看到原始 502 页面?大概率是以下情况之一:
- 后端返回的是
200 OK+ JSON 里写"code":502—— proxy_intercept_errors 只看 HTTP 状态码,不解析内容 -
error_page写在 server 块,但proxy_intercept_errors on;写在子 location 中,作用域不匹配 - 降级页文件不存在、权限不足,或 Nginx 无法读取,此时会触发新的 500 错误
- 静态资源代理(如
location ~ \.js$)也开了该指令,但这类 404 更适合用try_files处理


















