{"record":{"id":"685e15a84b36cb24","repo":"hashicorp/packer","slug":"os-detection-command-exited-with-status-d","errorCode":null,"errorMessage":"OS detection command exited with status %d","messagePattern":"OS detection command exited with status (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"provisioner/hcp-sbom/provisioner.go","lineNumber":390,"sourceCode":"\t\t\tCommand: \"echo %PROCESSOR_ARCHITECTURE%\",\n\t\t}\n\t} else {\n\t\tcmd = &packersdk.RemoteCmd{\n\t\t\tCommand: \"uname -s -m\",\n\t\t}\n\t}\n\n\tvar stdout bytes.Buffer\n\tcmd.Stdout = &stdout\n\n\tif err := comm.Start(ctx, cmd); err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"failed to run OS detection command: %s\", err)\n\t}\n\n\tcmd.Wait()\n\n\tif cmd.ExitStatus() != 0 {\n\t\treturn \"\", \"\", fmt.Errorf(\"OS detection command exited with status %d\", cmd.ExitStatus())\n\t}\n\n\toutput := strings.TrimSpace(stdout.String())\n\tlog.Printf(\"OS detection output: %s\", output)\n\n\t// Parse output\n\tvar osType, osArch string\n\tif connType == \"winrm\" {\n\t\tosType = \"Windows\"\n\t\tosArch = strings.ToLower(output) // AMD64, ARM64, etc.\n\t} else {\n\t\tparts := strings.Fields(output)\n\t\tif len(parts) >= 2 {\n\t\t\tosType = parts[0] // Linux, Darwin, FreeBSD, etc.\n\t\t\tosArch = parts[1] // x86_64, aarch64, etc.\n\t\t} else if len(parts) == 1 {\n\t\t\t// Some systems might only return one value\n\t\t\tosType = parts[0]","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/provisioner/hcp-sbom/provisioner.go#L372-L408","documentation":"detectRemoteOS runs an OS-detection command over the communicator (`uname -s -m` for SSH, `echo %PROCESSOR_ARCHITECTURE%` for WinRM) on the build machine. After the command finishes, it checks RemoteCmd.ExitStatus(); any non-zero exit status means the remote shell could not execute the command, so the provisioner aborts SBOM generation with this error. It is thrown by the hcp-sbom provisioner itself, not by the communicator.","triggerScenarios":"The remote OS-detection command returns a non-zero exit status: the target machine's default shell cannot execute `uname` (e.g. Windows SSH via cmd.exe/powershell where uname does not exist), the shell is restricted or not found, `set -e`-style profiles fail during login, or the WinRM command fails with %PROCESSOR_ARCHITECTURE% unset.","commonSituations":"Using an SSH communicator against a Windows guest without an OpenSSH bash/POSIX shell; a hardened/minimal image (distroless, busybox without coreutils full set) lacking `uname`; a broken login shell (bad .profile/.bashrc returning non-zero); restricted SSH accounts with forced commands or rbash blocking uname.","solutions":["Verify the build machine's shell can run `uname -s -m` (or `echo %PROCESSOR_ARCHITECTURE%` for winrm) by logging in with the same credentials and running it manually.","If building Windows guests over SSH, switch the communicator to winrm so the Windows-specific detection command is used.","Check the guest's login shell init files (.profile, .bashrc, /etc/profile) for commands that exit non-zero, or fix the account's shell to a valid POSIX shell.","Ensure the target image includes uname (install coreutils/util-linux) or pre-populate OSType/OSArch in generated_data so detection is skipped.","Inspect the Packer log for the exact exit status and any stderr from the remote command to pinpoint the failing shell."],"exampleFix":"// before (packer template using ssh for a Windows guest)\ncommunicator = \"ssh\"\nssh_username = \"Administrator\"\n\n// after: use winrm so the correct detection command runs\ncommunicator = \"winrm\"\nwinrm_username = \"Administrator\"\nwinrm_use_ssl = true","handlingStrategy":"try-catch","validationCode":"// Packer templates can't run code before, but you can validate the guest:\n// SSH into the machine with the same creds and run:\n//   ssh user@host 'uname -s -m' ; echo $?   # expect e.g. 'Linux x86_64' and status 0\n// For winrm targets confirm: winrs -r:host 'echo %PROCESSOR_ARCHITECTURE%'","typeGuard":null,"tryCatchPattern":"// In Go code embedding the provisioner:\nosType, osArch, err := p.detectRemoteOS(ctx, ui, comm, generatedData)\nif err != nil {\n    if strings.Contains(err.Error(), \"exited with status\") {\n        ui.Error(\"OS detection command failed on remote host; check shell/uname availability\")\n    }\n    return err // or fall back to a default OS/arch\n}","preventionTips":["Pre-populate OSType/OSArch in generated_data so detection is skipped","Use the winrm communicator for Windows guests instead of SSH","Keep guest login shells' init scripts exit-status clean","Ensure the target image ships uname/coreutils","Smoke-test `uname -s -m` in the same CI job before packer build"],"tags":["provisioner","ssh","winrm","os-detection","remote-command"],"backgroundTag":"remote-command-nonzero-exit","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}