{"record":{"id":"2fa7577746dd1907","repo":"oven-sh/bun","slug":"packer-build-exited-with-signal-signal-sign","errorCode":null,"errorMessage":"packer build exited with ${signal ? `signal ${signal}` : `code ${code}`}","messagePattern":"packer build exited with (.+?)` : `code (.+?)`\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/machine.mjs","lineNumber":1313,"sourceCode":"    },\n  });\n  let cancelled = false;\n  const forward = signal => {\n    cancelled = true;\n    console.log(`[packer] received ${signal}, forwarding to packer for Azure cleanup...`);\n    child.kill(signal);\n  };\n  process.on(\"SIGINT\", forward);\n  process.on(\"SIGTERM\", forward);\n  const [code, signal] = await new Promise(done => child.on(\"close\", (c, s) => done([c, s])));\n  process.off(\"SIGINT\", forward);\n  process.off(\"SIGTERM\", forward);\n  if (cancelled) {\n    console.log(\"[packer] cleanup after cancel finished\");\n    process.exit(1);\n  }\n  if (code !== 0) {\n    throw new Error(`packer build exited with ${signal ? `signal ${signal}` : `code ${code}`}`);\n  }\n\n  console.log(`[packer] Image built successfully: ${imageDefName}`);\n}\n\n/**\n * Download and install Packer if not already available.\n */\nasync function ensurePacker() {\n  // Check if packer is already in PATH\n  const packerPath = which(\"packer\");\n  if (packerPath) {\n    console.log(\"[packer] Found:\", packerPath);\n    return packerPath;\n  }\n\n  // Check if we have a local copy\n  const localPacker = join(tmpdir(), \"packer\");","sourceCodeStart":1295,"sourceCodeEnd":1331,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/scripts/machine.mjs#L1295-L1331","documentation":"The final gate of buildWindowsImageWithPacker(): `packer build` ran with forwarded SIGINT/SIGTERM, and after the child closed its exit code was non-zero (or it died to a signal). Packer's real error — the failing provisioner/build step — is in the output printed above this throw, not in the message itself.","triggerScenarios":"Azure build errors: auth expiry mid-build, quota/capacity failures, WinRM connection timeouts (especially x64-on-ARM emulation slowness); packer plugin init/download failures; the job being signalled (signal appears in the message).","commonSituations":"Transient Azure/WinRM flakes on Windows arm64 bakes; stale AZURE_* credentials; cancelled CI jobs forwarding SIGTERM into packer.","solutions":["Scroll up in the job log — packer prints the exact failing step (e.g. WinRM timeout, artifact upload) before this throw","Fix the named cause: rotate creds, request quota, or fix the bootstrap script","Re-run the bake: WinRM/Azure transient failures are common and often pass on retry","If the message says 'signal SIGTERM/SIGINT', the job was cancelled — retrigger it"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Fail fast before a 30+ minute bake if credentials are already bad\nawait getAzureToken(tenantId, clientId, clientSecret);\nif (!existsSync(templateFile)) throw new Error(`missing packer template: ${templateFile}`);","typeGuard":null,"tryCatchPattern":"try {\n  await buildWindowsImageWithPacker(opts);\n} catch (error) {\n  if (/signal/i.test(String(error))) {\n    // job was cancelled — retrigger instead of 'fixing' anything\n  } else {\n    // the real failing step is in packer's log above this throw — triage it, then retry once\n  }\n  throw error;\n}","preventionTips":["Always read the packer log above the throw — it names the failing step","Re-run once before debugging: WinRM/Azure transient failures are common on Windows bakes","Keep AZURE_* secrets fresh; tokens expiring mid-bake surface here as generic non-zero exits"],"tags":["packer","azure","build","ci"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}