Image size and format limits: common mistakes
An image error rarely names the exact cause outright. Where images actually get rejected on input, and how to debug it fast.
5 min · · Updated · изображения · errors
Update, October 2026. Image generation through Zukko is temporarily unavailable. The current model list is on the Models page or at
GET https://api.zukko.pro/v1/models. Closest replacement: there is no direct replacement among the available models; for image analysis (vision), the Claude and GPT models work, e.g.claude-sonnet-5orgpt-5.6-sol.
A request carrying an image — into edit, reference, or a vision model's input — fails differently than a plain text one. A text error usually comes back with a readable message; an image error tends to collapse into a generic 400 without pinpointing what's actually wrong with the file. Here's where images actually get rejected over size and format, and how to check it without guessing.
The gateway doesn't publish fixed numbers
Image generation and editing (/v1/images/generations) has no single published limit in megabytes or pixels that you can memorize once and stop checking. Different model families — the nano-banana-2-* line and the openai-gpt-image-* line — each validate incoming files on their own terms, and it's the specific model that decides what resolution and file weight it will accept. On this front the gateway mostly passes the request through and returns the model's own response as-is, rather than substituting its own unified check.
The practical takeaway: don't hardcode a constant like "10 MB max" anywhere in a project — it might hold for one model and be entirely wrong for another. Go by the text of the actual error, not by memory of a past successful call to a different model.
How to read an error response
If a file gets rejected over format or size, the response comes back as a 400 with a message in the message field — that's usually where the specifics live: unsupported format, resolution too large, corrupted data. Read that field literally rather than against a documentation template, because the wording depends on which model is handling the request.
curl https://api.zukko.pro/v1/images/generations \
-H "Authorization: Bearer fetch_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "nano-banana-2-edit-developer",
"prompt": "remove the background, keep only the object",
"images": ["data:image/bmp;base64,Qk1..."]
}' -iIf a model can't handle a given format (BMP in the example above), the message almost always names the format outright, and that's the fastest signal to re-encode the file rather than dig further into the request's structure.
The safe format choice
PNG and JPEG are accepted in practice by every catalogue model that handles images (GLM models have no vision, so sending them images is pointless) — the most predictable choice for input images, whether for edit, reference, or vision input through /v1/messages and /v1/chat/completions. WebP usually goes through too, but if a model returns a format error on WebP, the first thing worth trying is re-saving the file as PNG before encoding.
It's also worth checking that media_type (Anthropic schema) or the data:image/...;base64, prefix (OpenAI schema) matches the file's actual format rather than its filename extension. A file that's really PNG but labeled image/jpeg doesn't always throw a clean error — sometimes the model just reads the content worse, and untangling that later takes longer than checking the first few bytes before sending.
Source resolution matters in practice, not on paper
The gateway publishes no formal resolution limit, but in practice a very high resolution linearly inflates the base64 string's weight in the request body, and for vision requests it also inflates the number of tokens spent processing the image. If the task is editing or referencing rather than reading fine detail precisely, it's reasonable to downsize the source to a resolution that still preserves the needed detail without carrying extra weight. That's not a model requirement so much as a way to avoid hitting a body-size limit before you ever hit a format one.
Multiple images in one request
The images field in reference and edit modes is an array, and several files can be sent at once. Each added file grows the request body's weight, and with several high-resolution images the combined size grows faster than it looks. If a single-image request goes through but a multi-image one doesn't, the likely cause isn't format — it's the accumulated body weight: lower each file's resolution or send fewer of them.
Vision requests fail for the same reasons
Everything above about format and file weight isn't limited to /v1/images/generations — the same constraints apply when an image goes into a vision-capable text model through /v1/messages or /v1/chat/completions. The difference is that there, an image formatting error more often hides behind a generic 400 "invalid content," because the model primarily expects text and treats the image as just one block inside content. If a text-only request goes through but the same one with an image doesn't, check the same three things first: format, whether media_type matches the actual file, and the base64 string's weight — rather than hunting through the rest of the request.
A useful habit is running the body with the image through the free token count before the real call:
curl https://api.zukko.pro/v1/messages/count_tokens \
-H "Authorization: Bearer fetch_your_key" \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
-d '{"model":"claude-sonnet-5","messages":[{"role":"user","content":[{"type":"image","source":{"type":"base64","media_type":"image/png","data":"iVBORw0KG..."}}]}]}'If that request fails with a format error instead of just returning a token count, the problem really is the image itself, not the rest of the request — no need to keep digging into the model or the key.
The short version
Checking before sending comes down to three things: file format — PNG or JPEG as the safest pick, a correct media_type or data-URI prefix, and a sensible resolution without unnecessary headroom. After that, read the response message literally, because it comes from the specific model handling the request and usually names the cause directly.
zukko
Pay 25×
less
for Claude Code & ChatGPT
One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.
Related articles
- OpenAI API Keys in the Open: Why You Should Not Use ThemWhere free keys on GitHub come from, why using them is dangerous for you and for the owner, and how to protect your own key from the same leak.
- GLM API Errors: Why the Request Fails and How to Fix ItA wrong model id, an overflowing 128K context, the key, the balance, limits: the typical causes of GLM API errors and a quick way to find yours.
- This organization has been disabled in the Claude API: What to DoAn Anthropic key suddenly answers "organization has been disabled". What the error is, what to check, and how to move the SDK and Claude Code to another provider.
- JetBrains AI Assistant not working: causes and workaroundsAI Assistant will not activate, stays silent or is off for some files. We go through the causes in the JetBrains docs and connect your own models via a gateway.