Nginx 报 "stat() failed (13: Permission denied)" 怎么办?

Nginx stat() failed (13: Permission denied) 的修复:路径上每一级目录需要 x 权限,读取文件内容另需 r 权限;namei -l 逐级定位断点、SELinux 上下文检查与 FAQ。

最佳实践
Nginx 报 "stat() failed (13: Permission denied)" 怎么办?封面

这个错误表示 Nginx 想 stat()(读取元信息)某个文件/目录时被系统拒绝——本质是路径权限链上某一环把 Nginx 用户(www-data/nginx)挡在了外面。 用 namei -l 逐级查权限是最快的定位法。

修复步骤

1. 逐级检查权限链

namei -l /var/www/site/uploads/avatar.jpg

输出示例:

drwxr-xr-x root     root     /
drwxr-xr-x root     root     /var
drwxr-xr-x root     root     /var/www
drwxr-x--- deploy   deploy   /var/www/site      ← 断点在这
drwxr-xr-x deploy   deploy   /var/www/site/uploads
-rw-r--r-- deploy   deploy   /var/www/site/uploads/avatar.jpg

规则:stat 需要路径中每一级目录的 x(遍历)权限;读取文件内容还需要目标文件的 r 权限,对象是上层的"others"或 Nginx 所属组。上例中 /var/www/site 是 750 deploy:deploy,www-data 进不去 → stat 失败。

2. 修复断点

两种思路:

# 思路 A:放开目录权限(简单粗暴,注意家目录别这么干)
chmod 755 /var/www/site

# 思路 B:只给 Nginx 用户所需目录的遍历权限
setfacl -m u:www-data:--x /var/www/site
# 文件读取权限仍需单独核对

3. 高频场景:站点放在用户家目录

/home/alice/site/ 这类布局几乎必踩——/home/alice 默认 700 或 750,www-data 进不来。优先把站点挪到 /var/www/;必须留在家目录可用 setfacl -m u:www-data:--x /home/alice 只授予 Nginx 用户遍历权限,再检查站点目录和文件的必要权限。

4. SELinux(CentOS/RHEL)

权限链全对还报 13:

getenforce
ls -Z /var/www/site/        # 上下文应是 httpd_sys_content_t
sudo restorecon -Rv /var/www/site/

调整权限后,用同一 URL 重试,并核对 error.log 中的完整路径与错误码。若仍失败,继续检查权限链和安全策略,不要仅凭服务重载成功判断修复完成。

常见问题(FAQ)

Q:chmod 777 是不是万能解?
A:它不保证解决 SELinux、ACL 或其他安全策略问题,而且可能让任何本地用户修改站点文件——永远不要拿 777 当排障终点。正确答案是目录 755(或组 750)+ 文件 644 + 正确属主/属组。

Q:docker 挂载目录里也报这个?
A:可能与容器内用户的 UID/GID、目录权限或 SELinux 挂载标签有关;UID 不同本身不必然导致拒绝访问。要么调宿主机目录属主,要么容器以匹配 UID 运行,要么挂载时显式处理权限。

Q:stat() failed 和 open() failed 有区别吗?
A:stat 失败通常是路径中间某级目录进不去;open 失败也可能是中间目录无法遍历,或目标文件不可读。namei -l 一次把两层都看清。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台