kubernetes/kops · error
SSH agent has no keys
Error message
SSH agent has no keys
What it means
The connected ssh-agent returned zero signers: the agent socket is reachable but no identities are loaded (ssh-add -l is empty), so there is no key available to authenticate to the target host.
Source
Thrown at pkg/commands/toolbox_enroll.go:311
socket := os.Getenv("SSH_AUTH_SOCK")
if socket == "" {
return nil, fmt.Errorf("cannot connect to SSH agent; SSH_AUTH_SOCK env variable not set")
}
conn, err := net.Dial("unix", socket)
if err != nil {
return nil, fmt.Errorf("failed to connect to SSH agent with SSH_AUTH_SOCK %q: %w", socket, err)
}
agentClient := agent.NewClient(conn)
signers, err := agentClient.Signers()
if err != nil {
_ = conn.Close()
return nil, fmt.Errorf("failed to get signers: %w", err)
}
if len(signers) == 0 {
return nil, fmt.Errorf("SSH agent has no keys")
}
sshConfig := &ssh.ClientConfig{
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
klog.Warningf("accepting SSH key %v for %q", key, hostname)
return nil
},
Auth: []ssh.AuthMethod{
// Use a callback rather than PublicKeys so we only consult the
// agent once the remote server wants it.
ssh.PublicKeysCallback(agentClient.Signers),
},
User: sshUser,
}
// Use net.JoinHostPort so that IPv6 addresses are bracketed correctly.
sshClient, err := ssh.Dial("tcp", net.JoinHostPort(host, strconv.Itoa(sshPort)), sshConfig)
if err != nil {
return nil, fmt.Errorf("failed to SSH to %q (with user %q): %w", host, sshUser, err)View on GitHub (pinned to 4c8573c808)
Solutions
- Add a key to the agent: ssh-add ~/.ssh/id_<type>
- Confirm keys are loaded: ssh-add -l (should list at least one key)
- If re-running after failure, ensure a prior ssh-add -D wasn't executed or the agent restarted
- Test SSH manually first: ssh <user>@<host> should succeed using the same agent
Example fix
// before $ eval $(ssh-agent) $ kops toolbox enroll ... # Error: SSH agent has no keys // after $ eval $(ssh-agent) $ ssh-add ~/.ssh/id_ed25519 $ ssh-add -l # sanity check: lists the key $ kops toolbox enroll ...
Defensive patterns
Strategy: validation
Validate before calling
out, err := exec.Command("ssh-add", "-l").Output()
if err != nil || len(bytes.TrimSpace(out)) == 0 {
return fmt.Errorf("no keys in agent; run ssh-add <key>")
} Type guard
func agentHasKeys() bool {
out, err := exec.Command("ssh-add", "-l").Output()
return err == nil && len(bytes.TrimSpace(out)) > 0
} Try / catch
host, err := NewSSHHost(ctx, hostAddr, port, user, sudo)
if err != nil && strings.Contains(err.Error(), "SSH agent has no keys") {
return fmt.Errorf("load a key first: ssh-add ~/.ssh/id_ed25519")
} Prevention
- Run ssh-add -l as a preflight before enroll
- Add keys after every fresh eval $(ssh-agent)
- In CI, provision keys into the agent in the setup step
When it happens
Trigger: agentClient.Signers() returns an empty slice: the agent is running (often freshly started) but ssh-add was never run, or all keys were removed (ssh-add -D), or the forwarded agent belongs to a user/machine with no keys loaded.
Common situations: Starting a new CI job with an agent but forgetting to inject the key; ssh-add keys on a laptop then hopping through a bastion without forwarding; reboot cleared the agent's key cache.
Related errors
- cannot connect to SSH agent; SSH_AUTH_SOCK env variable not
- failed to connect to SSH agent with SSH_AUTH_SOCK %q: %w
- failed to get signers: %w
- failed to SSH to %q (with user %q): %w
- unable to SSH to %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/5670311ca5f4765a.
Report an issue: GitHub.