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-5 or gpt-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.

bash
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..."]
  }' -i

If 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:

bash
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.

Get API keyDocumentation

api.zukko.pro · fetch_*

Image size and format errors in the API explained · Zukko