oven-sh/bun · error
Failed to create gallery image definition: ${defResponse.sta
Error message
Failed to create gallery image definition: ${defResponse.status} ${await defResponse.text()} What it means
While publishing a Windows image, the script PUTs an image-definition create to the Azure Shared Image Gallery REST API and tolerates only 200 and 409 (already exists). Any other non-OK status throws with the status code and response body — auth/RBAC problems, a missing gallery (404), or an invalid payload.
Source
Thrown at scripts/machine.mjs:1205
method: "PUT",
headers: { "Authorization": `Bearer ${token}`, "Content-Type": "application/json" },
body: JSON.stringify({
location: location,
properties: {
osType: "Windows",
osState: "Generalized",
hyperVGeneration: "V2",
architecture: galleryArch,
identifier: { publisher: "bun", offer: `${os}-${arch}-ci`, sku: imageDefName },
features: [
{ name: "DiskControllerTypes", value: "SCSI, NVMe" },
{ name: "SecurityType", value: "TrustedLaunch" },
],
},
}),
});
if (!defResponse.ok && defResponse.status !== 409) {
throw new Error(`Failed to create gallery image definition: ${defResponse.status} ${await defResponse.text()}`);
}
// Packer's azure-arm shared_image_gallery_destination always writes
// image_version 1.0.0 and 409s if it already exists, so a re-run of
// [publish images] would fail on every Windows variant that already
// succeeded. Match the AWS path's deregister-then-recreate.
// CAUTION: unlike the AWS path (which only deregisters after the new
// create-image collides), this deletes the live version BEFORE Packer
// has produced a replacement. If this job is canceled or dies mid-bake,
// CI is left with no Windows image until a publish run completes.
const versionPath = `${galleryPath}/versions/1.0.0`;
const existing = await fetch(`https://management.azure.com${versionPath}?api-version=2024-03-03`, {
headers: { Authorization: `Bearer ${token}` },
});
if (existing.ok) {
console.log(`[packer] Deleting existing gallery image version 1.0.0 of ${imageDefName} before re-publish`);
const del = await fetch(`https://management.azure.com${versionPath}?api-version=2024-03-03`, {
method: "DELETE",View on GitHub (pinned to 8c5296ac45)
Solutions
- Read the status and body embedded in the error message — they name the exact ARM failure
- 403/401: verify the principal has Contributor on the gallery's resource group and the token tenant
- 404: verify AZURE_GALLERY_NAME and AZURE_RESOURCE_GROUP secrets against the real gallery
- Re-run publish once permissions/secrets are corrected
Defensive patterns
Strategy: try-catch
Validate before calling
// Cheap pre-flight: the gallery must exist and the token must work
const gallery = await fetch(`https://management.azure.com${galleryPath}?api-version=2024-03-03`, {
headers: { Authorization: `Bearer ${token}` },
});
if (gallery.status === 404) throw new Error('gallery/resource group not found — check AZURE_GALLERY_NAME secrets');
if (gallery.status === 401 || gallery.status === 403) throw new Error('token/RBAC problem on the gallery'); Try / catch
try {
await createImageDefinition(/* ... */);
} catch (error) {
// 409 is already handled upstream; anything else carries status+body — rethrow verbatim
throw error;
} Prevention
- Grant the CI principal Contributor on the gallery's resource group
- Keep AZURE_GALLERY_NAME/AZURE_RESOURCE_GROUP secrets in sync with the real Azure state
- Log the response body on every non-OK ARM call — statuses alone rarely identify the cause
When it happens
Trigger: The token's principal lacks Contributor on the resource group/gallery (403); AZURE_GALLERY_NAME/AZURE_RESOURCE_GROUP secrets point at a nonexistent gallery (404); expired token (401); identifier/publisher fields rejected by validation (400).
Common situations: New CI service principal without gallery RBAC; wrong gallery name secret after migrating galleries; token fetched for the wrong tenant/subscription.
Related errors
- Failed to delete existing gallery image version: ${del.statu
- [azure] Image replication failed: ${JSON.stringify(ver?.prop
- Delete of ${versionPath} failed: ${JSON.stringify(body)}
- Azure secret not found: ${name}
- [azure] ${method} ${path} failed: ${response.status} ${text}
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/563439c21d3d3c49.
Report an issue: GitHub.