Nginx默认不缓存404/500响应,需通过proxy_intercept_errors on配合error_page拦截并缓存自定义错误页,或用expires/Cache-Control为静态错误页配置强缓存,同时抑制原始错误响应的缓存。

后端返回 404 或 500 状态码时,Nginx 默认不缓存这些响应——这是合理默认行为,但实际中常需主动干预,否则可能造成错误页面反复回源、加重后端压力,或因浏览器缓存导致用户看到过期错误页。
明确是否由 Nginx 触发错误
缓存策略的前提是厘清错误来源:
- 若 404 来自 Nginx 本地(如文件不存在、
try_files落空),它可直接返回自定义静态页,此时应为该页配置强缓存(如expires 1d;) - 若 404/500 是后端应用返回的(如 Spring Boot 抛出异常),则需开启
proxy_intercept_errors on;,让 Nginx 拦截并接管响应,否则错误响应会原样透传给客户端,无法统一缓存 -
fastcgi_intercept_errors on;仅对 FastCGI 后端(如 PHP-FPM)有效,与代理场景无关,勿混淆使用
为拦截后的错误页设置合理缓存
一旦启用 proxy_intercept_errors 并通过 error_page 指向本地 HTML 文件,就可对这些页面做精细缓存控制:
- 在对应
location = /404.html { ... }块中添加:expires 1h;或add_header Cache-Control "public, max-age=3600"; - 避免用
expires -1s或no-cache,这会让浏览器每次重请求,失去错误页缓存意义 - 注意:若错误页体积小于 512 字节,部分旧版浏览器可能忽略
Cache-Control,建议保持页面内容适度充实(如加简短文案、样式或图标)
防止错误响应被意外缓存
对后端返回的原始 404/500(尚未被拦截时),可通过响应头抑制缓存:
- 在
location块中对后端代理路径添加:proxy_hide_header Cache-Control;配合add_header Cache-Control "no-store, no-cache, must-revalidate"; - 更稳妥做法是确保
proxy_intercept_errors on;已启用,并确认error_page配置生效,从根本上避免原始错误响应到达客户端 - 用
curl -I http://your-site/nonexistent验证响应头是否含预期Cache-Control,且状态码为 404 但内容为你自定义的页面
高并发下的稳定性补充
错误频发时,缓存策略还需配合限流与超时保护:
- 设置
proxy_read_timeout 5;,防止单个后端错误响应拖慢整个连接池 - 对错误页 location 使用
limit_req zone=errors burst=10 nodelay;(需提前定义 zone),避免大量错误请求冲击静态文件服务 - 日志中关注
upstream_cache_status变量,确认错误页是否命中本地缓存(值为HIT),而非反复读取磁盘或回源

















