kubernetes/kops · error

failed to get signers: %w

Error message

failed to get signers: %w

What it means

After dialing the agent socket, the code calls agentClient.Signers() to list keys the agent can sign with. A transport-level failure on the agent protocol (connection closed, protocol error) produces this wrapped error, and the connection is closed.

Source

Thrown at pkg/commands/toolbox_enroll.go:307

}

// NewSSHHost creates a new SSHHost.
func NewSSHHost(ctx context.Context, host string, sshPort int, sshUser string, sudo bool) (*SSHHost, error) {
	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,
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Verify the agent works: ssh-add -l must list keys without error
  2. Restart the agent: eval $(ssh-agent -s) && ssh-add
  3. Check SSH_AUTH_SOCK points to a real ssh-agent socket, not gpg-agent's non-SSH socket (enable SSH support in gpg-agent or use the ssh-agent socket path)
  4. Retry the command; if intermittent, inspect agent stability/logs

Example fix

// before
$ echo $SSH_AUTH_SOCK
/run/user/1000/gnupg/S.gpg-agent.extra   # not an SSH agent socket
// after
$ export SSH_AUTH_SOCK=$HOME/.gnupg/S.gpg-agent.ssh  # gpg-agent with enable-ssh-support
# or: eval $(ssh-agent -s) && ssh-add
Defensive patterns

Strategy: validation

Validate before calling

c, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
if err != nil { return err }
defer c.Close()
signers, err := agent.NewClient(c).Signers()
if err != nil { return fmt.Errorf("endpoint does not speak SSH agent protocol: %w", err) }

Type guard

func agentProtocolOK() bool {
    c, err := net.Dial("unix", os.Getenv("SSH_AUTH_SOCK"))
    if err != nil { return false }
    defer c.Close()
    _, err = agent.NewClient(c).Signers()
    return err == nil
}

Try / catch

host, err := NewSSHHost(ctx, hostAddr, port, user, sudo)
if err != nil && strings.Contains(err.Error(), "failed to get signers") {
    return fmt.Errorf("SSH_AUTH_SOCK points to a non-agent socket; check ssh-add -l")
}

Prevention

When it happens

Trigger: The unix socket connected but did not behave like an SSH agent — e.g. the path points to a different service's socket, the agent died between dial and Signers(), or the golang.org/x/crypto/ssh/agent handshake failed.

Common situations: SSH_AUTH_SOCK pointing at gpg-agent or a custom socket not speaking the SSH agent protocol; agent crashed mid-run; container socket forwarding breaking the stream.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/260a6a7da9e8fa4a. Report an issue: GitHub.