在Nginx中,server块定义的error_page不会被子location继承,子location一旦配置同码error_page即完全屏蔽上级设置,实现彻底接管而非叠加;未配置时则回退使用server级配置,且覆盖时须同步配置location、root/alias、proxy_intercept_errors等支撑指令。

在 Nginx 的 server 块中定义的 error_page 默认不会自动继承给子 location,但子 location 可以显式覆盖它——不是“继承后修改”,而是“直接屏蔽并替换”。
子 location 覆盖 error_page 的本质是屏蔽而非继承
error_page 在子 location 中一旦出现同码配置(如都定义了 error_page 404),就会完全屏蔽 server 级设置,上级配置不再参与处理。这不是叠加或补充,而是彻底接管。
- 若
location /api/内写了error_page 500 /500-api.html,则该路径下所有 500 错误都用这个页面,server级的/500-main.html不生效 - 若某个
location没写error_page,且其内部未触发更细粒度匹配(比如嵌套的location),则回退使用server级配置 -
location中定义的error_page仅作用于该location匹配范围,不向外影响其他路径
覆盖时需同步处理配套指令
单独改 error_page 不够,子 location 还得自己配好支撑逻辑,否则会 404 或权限拒绝:
- 如果指向本地文件(如
/404-api.html),必须在该location内或外层定义对应的location = /404-api.html,并确保root或alias正确、文件可读 - 若该
location是反向代理(proxy_pass),还需加proxy_intercept_errors on;,否则后端返回的错误压根不会被拦截 - 若想跳转到外部 URL 或重定向,要用
=302或命名 location +return,不能只靠error_page单独实现
常见覆盖失败原因
看似写了覆盖,却没生效,通常卡在这几个点:
-
location = /xxx.html里漏了root,或者拼出的物理路径不存在(比如root /usr/share/nginx/html;+error_page 404 /404.html→ 实际找的是/usr/share/nginx/html/404.html) - 用了
alias但路径少了一级斜杠,尤其在精确匹配=场景下容易错位 - 子
location中没启用proxy_intercept_errors on,导致代理错误根本进不了error_page流程 - 错误页面本身返回了 404(比如 HTML 引用了不存在的 CSS),触发二次
error_page,而recursive_error_pages默认关闭,链路中断
不写就是默认回退,写就是完全接管
location 块对 error_page 的控制非常明确:不声明,就用 server 级;一声明,就全权负责。不需要额外开关或继承开关,行为干净利落。关键在于配套资源和上下文指令是否同步到位。


















