Cross-session messaging silently disabled for secondary users on multi-user macOS (default socket dir /tmp/cc-socks is shared, first user owns it)
On a multi-user Mac, cross-session messaging works only for the first user
account that ever ran Claude Code. Every other user's sessions get messaging
silently disabled: CLAUDE_CODE_MESSAGING_SOCKET is never exported, so MCP
servers that depend on it fail, with no visible indication in the session
that the feature was turned off or why.
Environment
- Claude Code 2.1.243 (reproduces identically on 2.1.241), native install
- macOS 26.5.2 (build 25F84)
- Two local user accounts on the same machine
Steps to reproduce
- User A (uid 501) runs Claude Code. This creates
/tmp/cc-socks/owned by
A, mode 0700, and A's sessions get working cross-session messaging.
- Log into a second local account, user B (uid 502), and start a Claude Code
session there.
- In B's session, check the environment seen by any MCP server (or run
echo $CLAUDE_CODE_MESSAGING_SOCKET via the Bash tool).
Expected
B's sessions get their own messaging socket — or, at minimum, a visible
warning that cross-session messaging is off and why.
Actual
CLAUDE_CODE_MESSAGING_SOCKET is absent from B's sessions. Nothing in the
session UI indicates messaging was disabled. The only trace is a debug-level
log line ("Failed to set up sockets directory … refusing to bind —
cross-session messaging is OFF for this session"). Any MCP server relying on
the messaging socket fails with no user-diagnosable cause; we initially
misattributed it to a version regression.
Analysis
The messaging socket path resolves to $XDG_RUNTIME_DIR/cc-socks/<pid>.sock,
defaulting (via CLAUDE_CODE_TMPDIR → /tmp) to /tmp/cc-socks/<pid>.sock
on macOS, where XDG_RUNTIME_DIR is normally unset. /tmp is shared across
all users, so /tmp/cc-socks is created by whichever user runs Claude Code
first, with 0700 permissions. The socket-directory hardening introduced in
2.1.232 then correctly refuses the directory for every other user ("sockets
directory is owned by another user — refusing to use it") — but the refusal
is handled by silently disabling the feature rather than surfacing an error.
Two observations:
- The long-path fallback branch already solves this exact problem: when the
primary path exceeds the socket-path length limit, the code falls back to
/tmp/cc-socks-<uid>/<pid>.sock — per-user by construction. The primary
default just doesn't get the same uid suffix.
- 2.1.243's fix ("cross-session messaging silently turning off inside user
namespaces and rootless containers after the 2.1.232 socket-directory
hardening") does not cover this case: plain multi-user macOS, no
containers, still reproduces on 2.1.243.
Suggested fix
Any of:
- uid-suffix the default directory (
/tmp/cc-socks-<uid>), matching the
existing long-path fallback; or
- default to the per-user macOS temp dir (
$TMPDIR/
DARWIN_USER_TEMP_DIR) when it fits the socket-path length limit; and/or
- when the sockets-directory vet fails, surface a visible session warning
with the existing remediation text instead of only a debug log line — the
hardening's own error strings already name the fix, but users never see
them.
Workaround (verified)
Launch the affected user's sessions with a private socket directory:
mkdir -p ~/.claude/tmp && chmod 700 ~/.claude/tmp
CLAUDE_CODE_TMPDIR="$HOME/.claude/tmp" claude
XDG_RUNTIME_DIR works as well. Both restore messaging for the secondary
account immediately.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗