kubernetes/kops · error

error running command %q: %w

Error message

error running command %q: %w

What it means

Wraps a non-zero exit (or transport failure) from session.Run(command) when executing a command on the remote SSH host. The remote command itself failed; the underlying ssh error (often ExitError with exit status) is chained via %w. The command string is embedded for context.

Source

Thrown at pkg/commands/toolbox_enroll.go:409

		return nil, fmt.Errorf("failed to start SSH session: %w", err)
	}
	defer session.Close()

	output := &CommandOutput{}

	session.Stdout = &output.Stdout
	session.Stderr = &output.Stderr

	if options.Echo {
		// We send both to stderr, so we don't "corrupt" stdout
		session.Stdout = io.MultiWriter(os.Stderr, session.Stdout)
		session.Stderr = io.MultiWriter(os.Stderr, session.Stderr)
	}
	if s.sudo {
		command = "sudo " + command
	}
	if err := session.Run(command); err != nil {
		return output, fmt.Errorf("error running command %q: %w", command, err)
	}
	return output, nil
}

// getHostname gets the hostname of the SSH target.
// This is used as the node name when registering the node.
func (s *SSHHost) getHostname(ctx context.Context) (string, error) {
	output, err := s.runCommand(ctx, "hostname", ExecOptions{Echo: true})
	if err != nil {
		return "", fmt.Errorf("failed to get hostname: %w", err)
	}

	hostname := output.Stdout.String()
	hostname = strings.TrimSpace(hostname)
	if len(hostname) == 0 {
		return "", fmt.Errorf("hostname was empty")
	}
	return hostname, nil

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Rerun the command manually over SSH to see the actual stderr (Stderr is echoed to os.Stderr)
  2. Check the SSH user has passwordless sudo (s.sudo prefixes 'sudo '): test 'sudo -n true'
  3. Verify the command/binary exists on the target OS image
  4. Use errors.As on *ssh.ExitError to read the exit code and branch accordingly

Example fix

// before
_, err := host.runCommand(ctx, "kubeadm version", opts)
// after
var exitErr *ssh.ExitError
if errors.As(err, &exitErr) {
    log.Printf("remote cmd exited %d", exitErr.ExitStatus())
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check the command exists and sudo works
host.runCommand(ctx, "command -v "+binary, opts)
host.runCommand(ctx, "sudo -n true", opts)

Type guard

func isRemoteExitError(err error) (int, bool) {
    var e *ssh.ExitError
    if errors.As(err, &e) { return e.ExitStatus(), true }
    return -1, false
}

Try / catch

out, err := host.runCommand(ctx, cmd, opts)
if err != nil {
    if status, ok := isRemoteExitError(err); ok {
        return fmt.Errorf("%q failed with exit %d", cmd, status)
    }
    return err
}

Prevention

When it happens

Trigger: Any remote command run through SSHHost.runCommand exits non-zero — e.g. the 'hostname' command in getHostname, or a bootstrap/runScript step fails, or sudo is required but the user lacks passwordless sudo.

Common situations: SSH user lacks sudo privileges for the 'sudo ' prefixed command; command not installed on the node; kOps bootstrap script step fails on an unusual OS image; wrong SSH user/key.

Related errors


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