kovidgoyal/kitty · error

the ssh command: %s failed: %w with output: %s

Error message

the ssh command: %s failed: %w with output: %s

What it means

ControlMaster.check_call runs an ssh subcommand via CombinedOutput and wraps any non-zero exit or launch failure with the full argv and captured output. It indicates the multiplexed ssh control command itself failed (network, auth, or bad arguments). Start() calls it to establish the ControlMaster connection.

Source

Thrown at kittens/remote_file/actions.go:33

type ControlMaster struct {
	conn         *SSHConnectionData
	remote_path  string
	tdir         string
	Dest         string
	LastErrorLog string
}

func new_control_master(conn *SSHConnectionData, remote_path, dest string) *ControlMaster {
	return &ControlMaster{conn: conn, remote_path: remote_path, Dest: dest}
}

func (m *ControlMaster) check_call(argv []string) error {
	cmd := exec.Command(argv[0], argv[1:]...)
	cmd.Stdin = nil
	out, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("the ssh command: %s failed: %w with output: %s", strings.Join(argv, " "), err, string(out))
	}
	return nil
}

func (m *ControlMaster) Start() (err error) {
	if !m.conn.IsSSHKitten {
		if err = m.check_call(append(m.conn.cmd_prefix(), "-o", "ControlMaster=auto", "-fN", m.conn.Hostname)); err != nil {
			return err
		}
		if err = m.check_call(append(m.conn.batch_cmd_prefix(), "-O", "check", m.conn.Hostname)); err != nil {
			return err
		}
	}
	if m.Dest == "" {
		if m.tdir, err = os.MkdirTemp("", "kitty-remote-file"); err != nil {
			return err
		}
		m.Dest = filepath.Join(m.tdir, filepath.Base(m.remote_path))

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Run the printed ssh command manually to see the real error
  2. Remove stale control sockets (ControlPath, e.g. ssh -O exit host or delete socket files)
  3. Verify network connectivity and key auth (ssh -v host)
  4. Check that the hostname/binary passed in the ssh connection data is correct
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight: socket check
if _, err := os.Stat(master.SocketPath()); err == nil { /* stale socket? remove */ }

Try / catch

if err := master.Start(); err != nil {
    if strings.Contains(err.Error(), "failed") {
        // inspect wrapped output, clean sockets, retry once
    }
}

Prevention

When it happens

Trigger: Calling ControlMaster.Start() when ssh cannot reach the host, the control socket path is stale/broken, key authentication fails, or the ssh binary/args are malformed.

Common situations: SSH host key changed, agent not forwarded, ConnectionMultiplexing socket left over after reboot/network change, or a typo in hostname in --ssh-connection-data.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/bc650a1ce5dc3cf0. Report an issue: GitHub.