denoland/deno · error

Native addon cache directory '{}' is not private

Error message

Native addon cache directory '{}' is not private

What it means

Final Unix privacy check for Deno's native addon cache dir: the permission bits must be exactly 0o700. If they are looser, Deno attempts to chmod 0700 and re-stat; if the mode still is not 0700 (chmod failed or silently ignored by the filesystem), it errors with ErrorKind::PermissionDenied. Escaping to the user means the preferred dir was not salvageable and the fallback tempdir hit the same wall.

Source

Thrown at ext/rt_helper/lib.rs:274

  {
    use std::os::unix::fs::MetadataExt;
    use std::os::unix::fs::PermissionsExt;

    if metadata.uid() != current_uid() {
      return Err(std::io::Error::new(
        ErrorKind::PermissionDenied,
        format!(
          "Native addon cache directory '{}' is not owned by the current user",
          path.display()
        ),
      ));
    }

    if metadata.permissions().mode() & 0o777 != 0o700 {
      fs::set_permissions(path, fs::Permissions::from_mode(0o700))?;
      let metadata = fs::symlink_metadata(path)?;
      if metadata.permissions().mode() & 0o777 != 0o700 {
        return Err(std::io::Error::new(
          ErrorKind::PermissionDenied,
          format!(
            "Native addon cache directory '{}' is not private",
            path.display()
          ),
        ));
      }
    }
  }

  Ok(())
}

#[cfg(test)]
mod test {
  #![allow(clippy::disallowed_methods, reason = "test code")]

  use super::*;

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Move the temp dir to a POSIX filesystem that honors chmod: export TMPDIR=$(mktemp -d) under ext4/tmpfs.
  2. Manually repair the existing dir: chmod 700 "$TMPDIR"/deno-native-addon-cache, then rerun.
  3. For WSL, store the temp dir inside the Linux filesystem (not /mnt/c) or enable drvfs metadata.
  4. For NFS/shared volumes, use a per-user subdirectory created with 0700.

Example fix

# before
TMPDIR=/mnt/nfs-shared deno run app.ts # chmod does not stick -> not private

# after
export TMPDIR=/tmp/$(id -un)
mkdir -p "$TMPDIR" && chmod 700 "$TMPDIR"
deno run app.ts
Defensive patterns

Strategy: validation

Validate before calling

import { statSync, chmodSync, mkdirSync } from "node:fs";
const t = process.env.TMPDIR ?? "/tmp";
try { mkdirSync(t, { recursive: true, mode: 0o700 }); chmodSync(t, 0o700); } catch { throw new Error(`temp fs ignores chmod — use a POSIX filesystem for TMPDIR`); }
if ((statSync(t).mode & 0o777) !== 0o700) throw new Error(`temp dir not private: ${t}`);

Try / catch

try { await run(); } catch (e) { if (/is not private/.test(String(e))) throw new Error(`temp fs does not enforce 0700 (${t}) — remount TMPDIR on tmpfs/ext4`); throw e; }

Prevention

When it happens

Trigger: The cache directory has group/other bits set and the filesystem ignores or rejects set_permissions: NFS with root_squash, some FUSE/filesystem mounts, WSL drvfs mounts without metadata, or read-only filesystems where the repairing chmod fails.

Common situations: TMPDIR on an NFS home or shared volume; WSL1/NTFS-mounted temp dirs where POSIX modes do not stick; container volumes mounted with forced modes; umask-independent cases where an external tool loosened permissions.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/fd2bb4efd221e532. Report an issue: GitHub.