{"record":{"id":"df7b4fd2afdec0e5","repo":"oven-sh/bun","slug":"azure-image-replication-failed-json-stringify","errorCode":null,"errorMessage":"[azure] Image replication failed: ${JSON.stringify(ver?.properties)}","messagePattern":"\\[azure\\] Image replication failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/azure.mjs","lineNumber":627,"sourceCode":"      await ensureImageDefinition(imageDefName, os, arch);\n\n      // Create a single version \"1.0.0\" under this definition.\n      await createImageVersion(imageDefName, \"1.0.0\", vmId);\n\n      // Wait for image replication to complete before returning.\n      // Single-region replication typically takes 5-15 minutes.\n      const { galleryName } = config();\n      const versionPath = `${rgPath()}/providers/Microsoft.Compute/galleries/${galleryName}/images/${imageDefName}/versions/1.0.0`;\n      console.log(`[azure] Waiting for image replication...`);\n      for (let i = 0; i < 120; i++) {\n        const ver = await azureFetch(\"GET\", versionPath, undefined, GALLERY_API_VERSION);\n        const state = ver?.properties?.provisioningState;\n        if (state === \"Succeeded\") {\n          console.log(`[azure] Image ready: ${imageDefName}/1.0.0`);\n          break;\n        }\n        if (state === \"Failed\") {\n          throw new Error(`[azure] Image replication failed: ${JSON.stringify(ver?.properties)}`);\n        }\n        if (i % 6 === 0) {\n          console.log(`[azure] Image replicating... (${i}m elapsed)`);\n        }\n        await new Promise(r => setTimeout(r, 10_000));\n      }\n\n      return label;\n    };\n\n    const terminate = async () => {\n      await deleteVm(vmName);\n      // Resources with deleteOption=Delete are cleaned up automatically\n      // But clean up anything that might be left\n      await deleteNic(nicName);\n      await deletePublicIp(publicIpName);\n    };\n","sourceCodeStart":609,"sourceCodeEnd":645,"githubUrl":"https://github.com/oven-sh/bun/blob/8c5296ac459e8252d3cd702f3fbcbb0c249d95d5/scripts/azure.mjs#L609-L645","documentation":"Thrown while polling an Azure Compute Gallery image version (images/<definition>/versions/1.0.0) for replication: the loop in scripts/azure.mjs read provisioningState === \"Failed\" from the gallery API. The JSON of ver.properties is included so the failure reason is visible.","triggerScenarios":"Capturing the VM into a gallery image version whose replication to the target region failed — source VM removed before capture finished, gallery storage errors, region outages, or limits on the gallery.","commonSituations":"The image-build VM was deallocated/terminated before provisioningState reached Succeeded; Azure gallery replication incidents; subscription gallery limits reached.","solutions":["Inspect the properties JSON in the message for the exact failure code","Check per-region replication status: az sig image-version show for the 1.0.0 version","Delete the failed image version and re-run the image build so a fresh VM is captured","Confirm the gallery and target region are healthy before retrying"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await buildImage();\n} catch (e) {\n  if (e.message.includes(\"Image replication failed\")) {\n    await deleteImageVersion(\"1.0.0\"); // a stuck Failed version blocks the same name\n    return buildImage();\n  }\n  throw e;\n}","preventionTips":["Delete failed image versions before re-running — the fixed 1.0.0 name collides","Never terminate the source VM before provisioningState reads Succeeded"],"tags":["azure","ci","image-replication","gallery"],"backgroundTag":null,"analyzedSha":"8c5296ac459e8252d3cd702f3fbcbb0c249d95d5","analyzedAt":"2026-08-16T08:01:58.794Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}