← 中文资源

简体中文版本

Cargo 权限被拒绝 — target 目录不可写

通过修正 target/ 的所有权、避免多用户共享 target 目录,并清理残留锁,修复 cargo build 的权限被拒绝错误。

阅读英文原文

症状

遇到“Cargo 权限被拒绝 — target 目录不可写”时靠猜测只会浪费时间。请按证据排查:先复现症状,再执行针对性诊断,定位根因后修复,并用明确检查验证结果。

可观察到的症状包括:

  • cargo build 在 target/ 下报 “Permission denied (os error 13)”
  • 曾以 root 构建一次后开始报错
  • 只读挂载的 CI 缓存导致构建失败

诊断

先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。

步骤 1

ls -ld target target/debug && stat -c "%U %a" target/debug

用户目录下存在 root 拥有的文件,即可解释写入失败。

步骤 2

CARGO_TARGET_DIR=/tmp/cargo-target cargo build

构建到可写的临时目录成功,即把问题定位到原 target。

常见诱因(按出现频率排序):

  • 之前的构建以其他用户(常为 root)运行,使 target/ 文件不可写
  • target 目录位于只读挂载或权限错误的共享缓存上
  • .cargo-lock 被已死进程持有,成为残留锁

根因

Cargo 会在 target/ 下写入指纹、rlib 与锁。若这些文件属于其他用户,或位于只读挂载上,任何写入都返回 os error 13,编译无法进行。

修复

修正所有权(chown -R 到当前用户),避免以 root 构建,为 CI 提供可写的 CARGO_TARGET_DIR,并用 cargo clean 或删除 target/.cargo-lock 来清除残留锁。

注意:对容器内 target 做 chown -R 可能破坏其他挂载;应将改动限定在项目目录内。

# inspect and fix ownership
ls -ld target
sudo chown -R "$USER":"$USER" target

# or build into a clean, writable directory
CARGO_TARGET_DIR=/tmp/cargo-target cargo build --release

# clear a stale lock if a dead process held it
rm -f target/.cargo-lock

验证

以普通用户重跑 cargo build 并确认完成;验证 target 文件属于该用户。

修复后补充一条回归测试,复现原始症状,防止问题再次出现。

这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。