Common Image Generation API Errors and How to Fix Them
A practical troubleshooting guide for image generation API errors. 401, 403, 429, 500, and the silent failures nobody warns you about.
Every image generation API speaks roughly the same error language. Once you know the four or five common failures and the silent ones nobody mentions, debugging becomes fast. This is the field manual.
401 Unauthorized
Your API key is missing, malformed, or revoked. Check the Authorization header literally says Bearer followed by a space and the key. A leading space, a missing word Bearer, or a truncated key all return 401. If the request used to work and stopped, your key may have been rotated. Generate a new one in the dashboard.
403 Forbidden
Auth succeeded but the account is not allowed to make this request. Common causes are a suspended workspace, a missing plan, or the model you picked not being part of your tier. Check the response body for a code field and read the docs for that code.
429 Too Many Requests
You hit a rate limit. The response includes a Retry-After header in seconds. Honour it. Do not retry in a tight loop. A backoff with jitter prevents your retry storm from rate limiting yourself harder.
async function callWithBackoff(fn, max = 4) {
let attempt = 0;
while (attempt < max) {
const res = await fn();
if (res.status !== 429) return res;
const wait = Number(res.headers.get("retry-after")) || 2 ** attempt;
const jitter = Math.random() * 500;
await new Promise((r) => setTimeout(r, wait * 1000 + jitter));
attempt += 1;
}
throw new Error("rate limit retries exhausted");
}500 and 502 from upstream
The model crashed, a node went down, or the provider had an outage. Retry once with the same payload. If it still fails, switch to a different model slug as a fallback. Most outages are model specific, not platform wide.
Timeouts
Set the client timeout to at least 60 seconds for fast models and 120 for quality models. A common mistake is using the default 30 second fetch timeout, which kills the request just before the image arrives. The server keeps generating but you never receive the result.
Bad output that looks like a success
The API returns 200 and an image, but the image does not match the prompt or contains a watermark. Two fixes. Add a negative prompt that lists watermark, lowres, blurry, extra fingers. And generate two or three candidates with different seeds and let the user pick.
Silent failures nobody warns you about
- Free tier returns base64 but your code expected a URL. Always handle both.
- Browser CORS errors when calling from frontend code. Move the call to your backend.
- Image saved as a zero byte file because you wrote text instead of bytes. Use a binary write mode.
- Cache returns the wrong image because the cache key did not include the model slug. Include every parameter that affects the output in the key.
Where to look first when something breaks
- Print the request id from the response headers and search your logs.
- Hit the health endpoint to confirm the platform is up.
- Re run the same payload with curl. If curl works your client library is the problem.
- Check the dashboard for usage and quota. Hitting a daily cap returns 429 even when you are not burning rate limit.
Frequently asked questions
Try the API used in this article
Free tier, transparent pricing, and a single REST endpoint for FLUX, Stable Diffusion, and Leonardo models.
