{"record":{"id":"2b376650bbdb0326","repo":"kubernetes/kops","slug":"error-running-command-q-w","errorCode":null,"errorMessage":"error running command %q: %w","messagePattern":"error running command %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/toolbox_enroll.go","lineNumber":409,"sourceCode":"\t\treturn nil, fmt.Errorf(\"failed to start SSH session: %w\", err)\n\t}\n\tdefer session.Close()\n\n\toutput := &CommandOutput{}\n\n\tsession.Stdout = &output.Stdout\n\tsession.Stderr = &output.Stderr\n\n\tif options.Echo {\n\t\t// We send both to stderr, so we don't \"corrupt\" stdout\n\t\tsession.Stdout = io.MultiWriter(os.Stderr, session.Stdout)\n\t\tsession.Stderr = io.MultiWriter(os.Stderr, session.Stderr)\n\t}\n\tif s.sudo {\n\t\tcommand = \"sudo \" + command\n\t}\n\tif err := session.Run(command); err != nil {\n\t\treturn output, fmt.Errorf(\"error running command %q: %w\", command, err)\n\t}\n\treturn output, nil\n}\n\n// getHostname gets the hostname of the SSH target.\n// This is used as the node name when registering the node.\nfunc (s *SSHHost) getHostname(ctx context.Context) (string, error) {\n\toutput, err := s.runCommand(ctx, \"hostname\", ExecOptions{Echo: true})\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to get hostname: %w\", err)\n\t}\n\n\thostname := output.Stdout.String()\n\thostname = strings.TrimSpace(hostname)\n\tif len(hostname) == 0 {\n\t\treturn \"\", fmt.Errorf(\"hostname was empty\")\n\t}\n\treturn hostname, nil","sourceCodeStart":391,"sourceCodeEnd":427,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/commands/toolbox_enroll.go#L391-L427","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Rerun the command manually over SSH to see the actual stderr (Stderr is echoed to os.Stderr)","Check the SSH user has passwordless sudo (s.sudo prefixes 'sudo '): test 'sudo -n true'","Verify the command/binary exists on the target OS image","Use errors.As on *ssh.ExitError to read the exit code and branch accordingly"],"exampleFix":"// before\n_, err := host.runCommand(ctx, \"kubeadm version\", opts)\n// after\nvar exitErr *ssh.ExitError\nif errors.As(err, &exitErr) {\n    log.Printf(\"remote cmd exited %d\", exitErr.ExitStatus())\n}","handlingStrategy":"try-catch","validationCode":"// pre-check the command exists and sudo works\nhost.runCommand(ctx, \"command -v \"+binary, opts)\nhost.runCommand(ctx, \"sudo -n true\", opts)","typeGuard":"func isRemoteExitError(err error) (int, bool) {\n    var e *ssh.ExitError\n    if errors.As(err, &e) { return e.ExitStatus(), true }\n    return -1, false\n}","tryCatchPattern":"out, err := host.runCommand(ctx, cmd, opts)\nif err != nil {\n    if status, ok := isRemoteExitError(err); ok {\n        return fmt.Errorf(\"%q failed with exit %d\", cmd, status)\n    }\n    return err\n}","preventionTips":["Ensure the SSH user has passwordless sudo","Verify commands exist on the target OS image before enroll","Watch stderr (echoed to os.Stderr) for the real failure","Pin consistent OS images across nodes"],"tags":["ssh","remote-execution"],"backgroundTag":"remote-command-nonzero-exit","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}