Nginx默认不将后端返回的404视为故障,故不触发重试或故障转移;因404属正常HTTP响应,表示资源未找到而非连接失败、超时或5xx服务异常,仅当显式配置proxy_intercept_errors on和proxy_next_upstream http_404时才可启用重试。

Nginx 默认不把后端返回的 404 当作故障,也不会因此触发故障转移(即重试或切换上游服务器)。404 是 HTTP 正常响应状态码,代表“资源未找到”,Nginx 认为这次代理请求已成功完成——连接建立、请求发出、响应接收完整,只是业务层面没找到对应内容。
为什么 404 不触发故障转移
故障转移(如 proxy_next_upstream)只对真正的传输异常生效,比如:
- 连接失败(connection refused、timeout)
-
响应超时(
timeout) - 网关错误(500、502、503、504)
-
服务不可用信号(
error,含 TCP 层断连等)
而 404、401、403 等 4xx 响应,只要完整返回了状态行和头信息,Nginx 就视为一次成功的代理交互,不会进入重试逻辑。
如何让 404 触发重试
若业务场景确需将 404 视为“临时不可用”并尝试其他后端(例如多活部署中某台节点路由配置缺失),必须显式启用:
-
开启响应拦截:
proxy_intercept_errors on;(否则 4xx/5xx 直接透传,Nginx 不干预) -
声明重试条件:
proxy_next_upstream http_404;(可叠加error timeout) -
配合 error_page(可选但推荐):
error_page 404 = @retry;,再在@retry中重新 proxy_pass
注意:POST 等非幂等请求默认不重试,需额外加 non_idempotent 才生效。
更合理的处理思路
多数情况下,盲目重试 404 反而掩盖问题:
- 404 通常反映路径错配、部署遗漏、路由规则不一致等配置问题,换一台后端大概率仍返回 404
- 建议优先通过
max_fails/fail_timeout做健康检查,自动剔除长期异常节点 - 结合 access log 和 upstream_status 字段定位是哪台后端返回的 404,再查其日志确认是路由未匹配,还是上游 Nginx 自己返回(如 location 未命中)
- 对关键接口,可用
error_page 404 /fallback.html或转发至降级服务,而非简单重试
本质上,404 是语义明确的业务响应,不是链路故障。把它当故障处理,往往说明架构或部署环节存在更深层的一致性缺陷。


















