IMAGE_SAFETY — why the Gemini API returned no image (Nano Banana finishReason)
The exact error
IMAGE_SAFETY
What it means
IMAGE_SAFETY means the model refused to produce the image because a safety check fired on the image output. Google’s API errors page lists image_safety under “Generation blocked codes” and describes it as safety violations that blocked image generation. It sits next to image_prohibited_content, image_recitation and image_other, which cover other reasons an image can be blocked.
On a generateContent call to a Gemini image model (the Nano Banana family), the value arrives as the candidate’s finishReason. Users in google-gemini/.github issue #21 and python-genai issue #2024 both saw it there after asking for image output. The request itself does not fail with an error body. You get a normal response, but the candidate carries no image.
Google’s safety settings page explains the two layers involved. The adjustable filters cover four categories: harassment, hate speech, sexually explicit and dangerous content. Separately, the page says the Gemini API has built-in protections against core harms, such as content that endangers child safety, and that these “are always blocked and cannot be adjusted.”
What that means for your safetySettings is not fully documented, but there is a community report. In issue #21, the reporter set several categories to BLOCK_ONLY_HIGH, also tried BLOCK_NONE, and still got IMAGE_SAFETY when editing an ordinary photo of themselves. The same report says safetyRatings on the candidate came back undefined, so there was no category to inspect. Treat this as reported behavior, not an official statement. It does mean you should not expect relaxed thresholds to clear this finish reason.
How to confirm it’s this
- Read
candidates[0].finishReasonon the response. It isIMAGE_SAFETY, notSTOP. - The candidate has no image part. Check this before you try to decode anything.
- Look at
promptFeedback.blockReasontoo. Google’s safety settings page says that when it is set, the prompt itself was blocked, which is a different situation. - If you use the Interactions API, errors come back as an error object with a snake_case
code. Google’s errors page lists the blocked-generation code there asimage_safety.
If you use the Python SDK, python-genai issue #2024 reports that IMAGE_SAFETY was not recognized by the SDK’s FinishReason enum. The process printed a UserWarning that IMAGE_SAFETY is not a valid FinishReason and then hung while reading finish_reason. A maintainer asked for the exact model and prompt, noting the model in the report had been removed, and the issue was later closed as stale. The reporter’s own workaround was to wrap SDK property access in a thread with a timeout. If you see that warning, this finish reason is the likely cause.
Fix
This is a content decision made by Google’s filters, not a bug in your request, so the fix is in how you handle it:
- Treat it as a terminal result, not an empty success. Check the finish reason before reading image data. A handler that assumes an image is always present will crash or save an empty file.
- Surface it to whoever wrote the prompt. An agent should report that the image was blocked for safety, rather than silently returning nothing or quietly rewording the request.
- Check the input image as well as the text. Issue #21 was an edit of an uploaded photo, and the reporter found that some photos went through while most were blocked. That suggests the input image, not only the prompt, affects the outcome.
- If you believe it is a false positive, report it to Google. Keep the model name, the request and the finish reason. The
finishMessageon the closely relatedIMAGE_PROHIBITED_CONTENTresult, quoted in litellm issue #20357, asks you to send feedback if you think it was an error. - Do not rely on
BLOCK_NONE. Based on issue #21 and Google’s statement that some protections cannot be adjusted, lowering thresholds is not a dependable fix.
Retry or not
Do not retry the identical request automatically. Google’s errors page says that when you receive a generation-blocked code, you should modify your input and then retry. That is a change made by the person who owns the prompt, not a loop your agent runs. An automatic retry of the same input spends another generation with no documented reason to expect a different result.
If your agent asks the user for a revised request, that new request is a new call and can be sent normally.
When it’s not this
IMAGE_PROHIBITED_CONTENT: a separate finish reason. Google’s errors page ties it to prohibited content guidelines rather than safety violations. In litellm issue #20357 it came with afinishMessageexplaining the block.SAFETY: the general counterpart, not specific to image generation. Google’s safety settings page says you can inspectsafetyRatingsfor it.promptFeedback.blockReasonis set: the prompt was blocked before generation.- An HTTP 429 or 503: that is capacity or quota, not content. Those can be retried with backoff.
Related errors
- IMAGE_PROHIBITED_CONTENT
- 429 RESOURCE_EXHAUSTED
- 503 model overloaded
- OpenAI moderation_blocked
- fal content_policy_violation
Error text last verified against the sources below on .