SSH_AUTH_SOCK is set, but ssh-add still cannot connect? The variable doesn't contain a key or start an agent. It points SSH-aware programs to the agent's communication socket—and that socket may be missing, stale, or inaccessible from your current environment.
Understanding that distinction makes agent problems much easier to diagnose.
What the variable points to
An SSH agent holds identities and can perform authentication operations for programs such as ssh, ssh-add, and Git. Rather than giving each program direct access to a private-key file, the agent provides a socket that compatible programs can contact.
The relationship looks like this:
ssh, ssh-add, or Git
|
v
SSH_AUTH_SOCK (a path)
|
v
agent socket -> SSH agent -> loaded identities
Inspect the value in your current shell with:
echo "$SSH_AUTH_SOCK"
It might look like a path under /tmp, but the exact location varies. Don’t copy an example path into your shell configuration: it must point to a real socket created by the agent you intend to use.
Diagnose the current shell
Check the variable, the socket, and whether the agent responds:
printf '%s\n' "$SSH_AUTH_SOCK"
test -S "$SSH_AUTH_SOCK" && echo "socket exists"
ssh-add -l
These checks answer different questions:
- The variable is empty: this shell has no agent socket path in its environment.
-
The variable has a value, but
test -Sfails: the path may be stale, inaccessible, or not a Unix socket in this environment. -
ssh-add -llists fingerprints: the shell can reach an agent with loaded identities. - The agent reports no identities: it is reachable, but no keys are loaded.
- The agent connection fails: the current process cannot use a suitable agent through the socket it was given.
A non-empty variable is not proof that the agent is working. Long-running shells, terminal multiplexers, and reconnected sessions can keep an old path after its socket has disappeared.
Start an agent—or use the one you already have
For a temporary shell session using OpenSSH’s agent on Linux or another Unix-like system, run:
eval "$(ssh-agent -s)"
Then load a key if needed and check again:
ssh-add ~/.ssh/id_ed25519
ssh-add -l
The eval is important: ssh-agent is a child process and cannot change the environment of the shell that launched it. Evaluating its output applies the environment assignments to your current shell.
However, don’t automatically start another agent whenever something goes wrong. A desktop session, operating system, password manager, or other compatible agent may already be managing one. In that case, the right fix is to restore the environment provided by that agent—not to switch agents by launching a new one.
You can manually point a Bourne-style shell at a known socket:
export SSH_AUTH_SOCK=/path/to/agent.sock
This only changes where programs look. It does not create a socket or start an agent. If the path is wrong or no longer valid, the connection will still fail.
Why the value goes stale
The variable is inherited through process environments. A shell passes its environment to child processes, but an already-running process does not automatically receive later changes made elsewhere.
This can become visible with tmux. Its server can outlive the shell that started it, so a session may retain an older socket path after you reconnect. Inspect tmux’s stored value with:
tmux show-environment SSH_AUTH_SOCK
Updating tmux’s environment does not rewrite the environment of shells already running inside its panes. New panes are more likely to inherit the updated value. Also be cautious when attaching from a shell where the variable is unexpectedly empty: tmux’s environment update behavior can remove it from the session environment.
The same general lesson applies across containers and other process boundaries: check the environment where the failing command actually runs, not just the environment of a different terminal.
Using a host agent in a Linux container
On a Linux host, a container generally needs the agent socket mounted into it and SSH_AUTH_SOCK set to the mount path. A typical pattern is:
docker run --rm -it \
-v "$SSH_AUTH_SOCK:/ssh-agent" \
-e SSH_AUTH_SOCK=/ssh-agent \
your-image
Then check from inside the container:
ssh-add -l
This Linux-host example should not be copied blindly to Docker Desktop on macOS. Docker Desktop uses a VM and has its own agent-forwarding mechanism; the host socket path is not equivalent to a directly mountable Linux socket in that setup.
Treat socket access as sensitive. A process that can connect to the socket may be able to ask the agent to authenticate. Only expose it to containers you trust.
Agent forwarding is a separate case
With agent forwarding enabled, an SSH session can provide a temporary agent socket on the remote host. The remote shell’s SSH_AUTH_SOCK points to that forwarded socket while the connection is active. For example:
ssh -A user@server
Your private-key file is not copied to the remote machine. But the remote environment can still ask your local agent to perform authentication operations while forwarding is available. Enable forwarding only for hosts and workflows you trust; avoid turning it on globally just for convenience.
The practical checklist
When SSH authentication through an agent fails, check the environment in the same shell or process that runs the failing command:
echo "$SSH_AUTH_SOCK"
test -S "$SSH_AUTH_SOCK" && echo "socket exists"
ssh-add -l
If the value is empty, determine whether your session should already provide an agent before starting another one. If the socket is missing, look for a stale environment rather than guessing a replacement path. If the agent responds but has no identities, load the key into the intended agent.
The key idea is simple: SSH_AUTH_SOCK is an address, not the agent itself. Fixing the connection means making sure the address belongs to the right, reachable agent.
I originally published a more detailed version of this guide on the SSHFlow blog.
I'm also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.
Top comments (0)