[Bug] /tmp/claude-settings-<hash>.json shared across Linux users — second user crashes with EACCES (exit code 1)

Status Fixed / completed
Reported on v2.1.119
Maintainer reply None cached
Activity 3 comments · opened Apr 26, 2026 · closed Apr 26, 2026

Summary

When two or more Linux users on the same machine use Claude Code (Cowork / remote SSH agent), the second user's session crashes immediately with Claude Code process exited with code 1 because CCD writes its temporary settings file to /tmp/claude-settings-<hash>.json where the <hash> is not unique per-user. The first user to start a session creates the file owned by them; every subsequent user hits EACCES trying to overwrite it, even though the file is 0666.

Environment

  • Claude Desktop: 1.4758 (Windows host)
  • Remote agent CLI: ccd-cli 2.1.119
  • Server OS: Ubuntu 24.04, kernel default fs.protected_regular = 2
  • Two Linux users on the same VPS (tolya uid 1001, tim uid 1002), independent SSH keys, both connecting via Claude Desktop's remote-agent feature

Reproduction

  1. User A SSHs into the server via Claude Desktop's remote agent. Session starts fine; CCD creates /tmp/claude-settings-44136fa355b3678a.json (mode 664, owner=A).
  2. User B SSHs into the same server via Claude Desktop's remote agent.
  3. CCD spawns ccd-cli for user B. ccd-cli tries to open the same path with O_WRONLY|O_CREAT|O_TRUNC, 0666.
  4. Kernel returns EACCES because of fs.protected_regular: in a sticky-bit directory, you cannot O_CREAT an existing regular file you don't own (anti symlink/hardlink-attack hardening, on by default since kernel 4.19).

Actual behaviour

ccd-cli exits with code 1 within ~300-400 ms. Stderr (visible in ~/.claude/logs/ssh.log):

[RemoteProcess:...] stderr: Error processing settings: EACCES: permission denied, open '/tmp/claude-settings-44136fa355b3678a.json'
[RemoteProcess:...] Exited, code=1, duration=314ms

The hash 44136fa355b3678a is identical for every user on the host.

$ ls -la /tmp/claude-settings-*
-rw-rw-r-- 1 userA userA 2 Apr 26 06:15 /tmp/claude-settings-44136fa355b3678a.json

$ sudo -u userB strace -e openat -f -- bash -c 'echo {} > /tmp/claude-settings-44136fa355b3678a.json'
openat(AT_FDCWD, "/tmp/claude-settings-44136fa355b3678a.json", O_WRONLY|O_CREAT|O_TRUNC, 0666) = -1 EACCES (Permission denied)

chmod 666 does not fix it — the kernel block is on O_CREAT of an existing regular file you don't own in a sticky directory, regardless of mode.

Expected behaviour

The settings file path should include something user-unique (UID, $USER, or $HOME in the hash input), so each Linux user gets their own file.

Workaround

Delete the file as root before the second user starts a session:

sudo rm /tmp/claude-settings-*.json

This works once but breaks the original user's next session, because now they hit the same EACCES.

Suggested fix

Use any of these instead of /tmp/claude-settings-<hash>.json:

  • $XDG_RUNTIME_DIR/claude-settings-<hash>.json — systemd already creates /run/user/<uid> with mode 700 per user
  • $HOME/.cache/claude/settings-<hash>.json
  • Include UID / $USER in the hash input so the path becomes per-user even in /tmp

Notes

  • Same bug presumably affects any other multi-user Linux dev box (shared dev servers are a common Claude Code remote-agent setup).
  • Doesn't reproduce on single-user installs (macOS/Windows) because there's only one user touching the file.

View original on GitHub ↗

3 Comments

github-actions[bot] · 5 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/52036
  2. https://github.com/anthropics/claude-code/issues/52111
  3. https://github.com/anthropics/claude-code/issues/53425

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

TimChesko · 5 months ago

Working workaround on a multi-user Linux host

If you control the host, set per-user TMPDIR via PAM so it applies to non-interactive SSH sessions (where /etc/profile.d/* is not sourced):

# 1) ensure pam_env is enabled in the SSH stack (default on Ubuntu)
grep pam_env /etc/pam.d/sshd
# you should see something like:
#   session    required     pam_env.so

# 2) add per-user TMPDIR
echo 'TMPDIR DEFAULT=@{HOME}/.cache/tmp' | sudo tee -a /etc/security/pam_env.conf

# 3) ensure the dir exists for each dev user
for u in alice bob; do
  sudo -u "$u" mkdir -p "/home/$u/.cache/tmp"
done

# 4) clean any stale shared file and kill running CCD remote-servers
sudo rm -f /tmp/claude-settings-*.json
sudo pkill -u alice -f claude/remote || true
sudo pkill -u bob   -f claude/remote || true

After this, each user reconnects from Claude Desktop. The remote-server inherits TMPDIR=$HOME/.cache/tmp from PAM, ccd-cli inherits from remote-server, and the settings file lands in the per-user dir — no more shared /tmp collision.

Verified on Ubuntu 24.04 + ccd-cli 2.1.119 + Claude Desktop 1.4758. Both users now have isolated claude-settings-44136fa355b3678a.json files in their own ~/.cache/tmp/ and can run Claude Code remote sessions concurrently.

This is a workaround — the underlying bug (sharing the path across users on the same host) should still be fixed in CCD itself per the OP's "Suggested fix".

github-actions[bot] · 5 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.