recursive_error_pages 不用于解决HTTP错误页面死循环,而是控制error_page子请求失败后是否启用二级容错;死循环源于error_page规则设计缺陷(如404→/error.php→500→/error.php),与该指令无关。

什么是 recursive_error_pages?
它控制 Nginx 在处理 error_page 指令时,是否允许对 错误页面的响应结果再次执行 error_page 匹配。默认为 off,即:
→ 用户请求 /a → 返回 404 → 触发 error_page 404 /404.html
→ Nginx 内部发起子请求 GET /404.html
→ 若 /404.html 本身也出错(比如文件权限不对、返回 500),Nginx 不会再用 error_page 处理这个子请求的失败,而是直接返回原始 404 或底层错误(如 500)。
设为 on 后,上述子请求若失败(如 /404.html 返回 500),Nginx 会再次尝试用 error_page 500 去找另一个兜底页(如 /5xx.html),形成“递归处理错误”的能力——但这不是“修复死循环”,而是**启用二级容错机制**。
真正的“错误页面死循环”长什么样?
典型死循环场景是:error_page 指向的 URI 自身又触发了同个错误码,且未加保护。例如:
- 配置:
error_page 404 /error.php; - /error.php 本身不存在,或 PHP 执行出错返回 500
- 同时又配了:
error_page 500 /error.php; - → 404 → /error.php → 500 → /error.php → … 无限循环(Nginx 会主动截断,返回 500)
这种循环与 recursive_error_pages 无关,而是 error_page 规则设计缺陷所致。
如何安全配置,避免循环?
- 错误页面用静态资源:/404.html、/50x.html 等纯 HTML 文件,不依赖后端执行,杜绝二次出错
-
隔离错误处理路径:确保
error_page指向的 URI 不在受保护或易出错的 location 块中(例如不要指向 /api/ 下的脚本) -
禁用递归,除非明确需要多级兜底:保持
recursive_error_pages off;(默认值),更可控 -
用 try_files 防止子请求失败:对动态错误页,可加判断:
location = /error.php {<br> try_files /error.html =404;<br> fastcgi_pass ...;<br>}这样即使 PHP 挂了,也会 fallback 到静态页

















