{"record":{"id":"61dd29bcac8cff9d","repo":"denoland/deno","slug":"native-addon-cache-directory-is-not-owned-by","errorCode":null,"errorMessage":"Native addon cache directory '{}' is not owned by the current user","messagePattern":"Native addon cache directory '(.+?)' is not owned by the current user","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ext/rt_helper/lib.rs","lineNumber":261,"sourceCode":"  if metadata.file_type().is_symlink() || !metadata.is_dir() {\n    return Err(std::io::Error::new(\n      ErrorKind::PermissionDenied,\n      format!(\n        \"Native addon cache path '{}' is not a private directory\",\n        path.display()\n      ),\n    ));\n  }\n\n  // Windows temp directories are normally per-user; Unix additionally\n  // enforces ownership and mode here.\n  #[cfg(unix)]\n  {\n    use std::os::unix::fs::MetadataExt;\n    use std::os::unix::fs::PermissionsExt;\n\n    if metadata.uid() != current_uid() {\n      return Err(std::io::Error::new(\n        ErrorKind::PermissionDenied,\n        format!(\n          \"Native addon cache directory '{}' is not owned by the current user\",\n          path.display()\n        ),\n      ));\n    }\n\n    if metadata.permissions().mode() & 0o777 != 0o700 {\n      fs::set_permissions(path, fs::Permissions::from_mode(0o700))?;\n      let metadata = fs::symlink_metadata(path)?;\n      if metadata.permissions().mode() & 0o777 != 0o700 {\n        return Err(std::io::Error::new(\n          ErrorKind::PermissionDenied,\n          format!(\n            \"Native addon cache directory '{}' is not private\",\n            path.display()\n          ),","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/rt_helper/lib.rs#L243-L279","documentation":"Unix-only ownership check in Deno's native addon cache validation: fs::symlink_metadata().uid() must equal the current process uid, or the directory is rejected with ErrorKind::PermissionDenied. A cache directory owned by another user could be pre-populated or tampered with, so Deno refuses it. This message escaping also implies the fresh-tempdir fallback failed (e.g. the temp filesystem reports on-disk uids that do not match the process uid).","triggerScenarios":"The cache dir under TMPDIR was created by another uid (earlier sudo run, image build step, other user on a shared box), or the temp filesystem is an idmapped/userns mount where the on-disk uid never matches the in-namespace current uid, so even a freshly created fallback dir fails the equality check.","commonSituations":"Running deno once with sudo then again as a normal user; rootless containers with uid remapping; bind-mounted volumes from a different uid; CI caches restored with preserved ownership; shared multi-user machines.","solutions":["Remove the foreign-owned cache dir: sudo rm -rf \"$TMPDIR\"/deno-native-addon-cache (or the reported path), then rerun as the intended user.","Point TMPDIR at a directory owned by the current uid: export TMPDIR=$(mktemp -d).","In containers, run as a consistent uid (USER directive) and avoid uid-remapped mounts for the temp dir.","Never mix sudo and non-sudo runs against the same temp/cache location."],"exampleFix":"# before\nsudo deno run app.ts   # creates root-owned cache dir\n deno run app.ts       # PermissionDenied: not owned by the current user\n\n# after\nsudo rm -rf \"$TMPDIR\"/deno-native-addon-cache\ndeno run app.ts","handlingStrategy":"validation","validationCode":"import { statSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nconst t = process.env.TMPDIR ?? tmpdir();\nconst st = statSync(t, { throwIfNoEntry: false });\nif (st && process.getuid && st.uid !== process.getuid()) throw new Error(`TMPDIR owned by uid ${st.uid}, running as ${process.getuid()} — pick a per-user temp dir`);","typeGuard":null,"tryCatchPattern":"try { await run(); } catch (e) { if (/not owned by the current user/.test(String(e))) throw new Error(`stale cache dir with foreign owner under TMPDIR — remove it and rerun: rm -rf ${t}/deno-native-addon-cache`); throw e; }","preventionTips":["Never alternate sudo and non-sudo runs against the same TMPDIR/cache.","In containers, keep a fixed USER and avoid uid-remapped mounts for temp dirs.","Set TMPDIR to a per-user directory (mktemp -d or /tmp/$(id -un)) in multi-user environments."],"tags":["native-addons","cache","permissions","unix","ownership","containers"],"backgroundTag":"insecure-temp-directory","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}