oven-sh/bun · error · Error
[azure] ${method} ${path} failed after 3 retries
Error message
[azure] ${method} ${path} failed after 3 retries What it means
The REST helper attempted the call 3 times and every attempt hit a retryable condition (the loop retries transient statuses before reaching this throw), so the request never got a final answer. This is exhaustion of the fixed 3-attempt budget rather than a single hard failure.
Source
Thrown at scripts/azure.mjs:143
if (operationUrl) {
return waitForOperation(operationUrl);
}
}
if (response.status === 204) {
return null;
}
if (!response.ok) {
const text = await response.text();
throw new Error(`[azure] ${method} ${path} failed: ${response.status} ${text}`);
}
const text = await response.text();
return text ? JSON.parse(text) : null;
}
throw new Error(`[azure] ${method} ${path} failed after 3 retries`);
}
async function waitForOperation(operationUrl, maxWaitMs = 3_600_000) {
const start = Date.now();
let fetchErrors = 0;
while (Date.now() - start < maxWaitMs) {
const token = await getAccessToken();
let response;
try {
response = await fetch(operationUrl, {
headers: { Authorization: `Bearer ${token}` },
});
} catch (err) {
fetchErrors++;
if (fetchErrors > 10) {
throw new Error(`[azure] Operation poll failed after ${fetchErrors} fetch errors`, { cause: err });View on GitHub (pinned to 8c5296ac45)
Solutions
- Wait and re-run — transient Azure throttling usually clears
- Space out concurrent azure.mjs jobs hitting the same subscription/resource group
- Raise the retry count or backoff in the request helper if the workload is legitimately bursty
Example fix
// before
for (let i = 0; i < 3; i++) { ... }
throw new Error(`[azure] ${method} ${path} failed after 3 retries`);
// after
for (let i = 0; i < 5; i++) { ... /* honor retry-after when present */ }
throw new Error(`[azure] ${method} ${path} failed after 5 retries`); Defensive patterns
Strategy: retry
Prevention
- Stagger concurrent azure.mjs jobs sharing one subscription to avoid throttle exhaustion
- Honor the retry-after header when present instead of fixed backoff
- Make the whole pipeline re-runnable so exhausting retries is cheap
When it happens
Trigger: Azure ARM continuously returning retryable statuses (429 throttling, 5xx) for all three attempts; backoff between attempts too short relative to the throttle window.
Common situations: Subscription-level throttling during heavy parallel image builds; an Azure regional incident lasting longer than the retry budget.
Related errors
- [azure] Operation poll failed after ${fetchErrors} fetch err
- [azure] Failed to get public IP for ${vmName}
- GitHub API rate limit exceeded after ${maxRetries} retries
- Azure secret not found: ${name}
- [azure] Auth failed: ${response.status} ${await response.tex
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/56523c9ca74ccc35.
Report an issue: GitHub.