# Nano Banana 2 blockReason OTHER 오류 해결: 원인 미공개일 때 확인할 것

> Google은 blockReason OTHER를 '알 수 없는 이유로 프롬프트가 차단됨'으로만 정의합니다. 안전 설정으로 풀린다는 근거가 없으니 응답을 저장하고 변수 하나씩 바꿔 원인을 좁히세요.

- URL: https://blog.laozhang.ai/ko/posts/nano-banana-2-blockreason-other
- Published: 2026-03-09
- Updated: 2026-10-04
- Author: LaoZhang AI Team (https://blog.laozhang.ai/ko/about)
- Topic: API 가이드
- Tags: Nano Banana 2, blockReason OTHER, Gemini API, finishReason, 이미지 생성 오류

---
`generateContent`로 Nano Banana 2(`gemini-3.1-flash-image`)나 Nano Banana Pro(`gemini-3-pro-image`)를 호출했는데 `candidates` 없이 `"promptFeedback": {"blockReason": "OTHER"}`만 돌아왔다면, 확실한 사실은 두 가지입니다. 프롬프트 단계에서 요청이 차단되어 이미지가 만들어지지 않았다는 것, 그리고 Google이 그 이유를 응답에 알려 주지 않는다는 것입니다. Google의 [GenerateContent API 참조](https://ai.google.dev/api/generate-content#BlockReason)는 `OTHER`를 "Prompt was blocked due to unknown reasons", 즉 알 수 없는 이유로 프롬프트가 차단됐다고만 설명합니다.

그래서 해결은 숨은 규칙을 추측하는 데서 시작하지 않습니다. 원본 응답과 요청 조건을 저장하고, 코드에서 이 응답을 성공도 일시 오류도 아닌 별도 결과로 처리한 뒤, 변수 하나씩만 바꿔 어떤 조건에서 차단되는지 좁힙니다. 그래도 좁혀지지 않으면 같은 요청을 계속 보내지 말고 증거를 정리해 Google에 문의하는 편이 낫습니다. 프록시나 돌려 쓴 표현으로 차단을 피하려는 시도는 원인을 밝혀 주지도 않고 정책 위반이 될 수 있습니다.

## blockReason OTHER의 공식 정의: 프롬프트 차단, 이유는 알 수 없음

Google API 참조에서 `promptFeedback.blockReason` 필드 설명은 이렇습니다. "설정되어 있으면 프롬프트가 차단되었고 후보(candidates)는 반환되지 않는다. 프롬프트를 바꿔 다시 작성하라(Rephrase the prompt)." 같은 문서는 API가 후보를 전혀 반환하지 않는 경우를 "프롬프트에 문제가 있을 때뿐"이라고 적고 있습니다. 2026년 10월 4일 기준 `BlockReason` 열거형은 다음 여섯 값입니다.

| 값 | Google 문서의 설명 | 참고할 필드 |
| --- | --- | --- |
| `BLOCK_REASON_UNSPECIFIED` | 기본값, 사용되지 않음 | 해당 없음 |
| `SAFETY` | 안전상의 이유로 차단 | `promptFeedback.safetyRatings`에서 어느 범주인지 확인하라고 문서에 명시 |
| `OTHER` | 알 수 없는 이유로 차단 | 문서에 안내된 추가 필드 없음 |
| `BLOCKLIST` | 용어 차단 목록에 포함된 단어 때문에 차단 | 문서에 안내된 추가 필드 없음 |
| `PROHIBITED_CONTENT` | 금지된 콘텐츠 때문에 차단 | 문서에 안내된 추가 필드 없음 |
| `IMAGE_SAFETY` | 안전하지 않은 이미지 생성 콘텐츠 때문에 후보 차단 | 문서에 안내된 추가 필드 없음 |

이 정의에서 알 수 있는 것과 알 수 없는 것을 나누면 다음과 같습니다.

- **알 수 있는 것**: 프롬프트(텍스트와 첨부 이미지를 포함한 요청 내용)가 차단되었고, 후보가 만들어지지 않았으며, 그 응답에는 이미지가 없습니다. 문서가 제시하는 공식 조치는 "프롬프트를 바꿔 작성하라"입니다.
- **알 수 없는 것**: 어떤 규칙이나 시스템이 차단했는지, 원인이 텍스트인지 참조 이미지인지 계정·프로젝트 쪽인지, 같은 요청을 다시 보내면 결과가 달라지는지. Google은 `OTHER` 뒤에 있는 차단 구조나 콘텐츠 범주 목록을 공개하지 않습니다.

따라서 "OTHER는 설정할 수 없는 별도 단계의 정책 필터다", "OTHER를 일으키는 범주가 몇 가지 있다", "특정 시점에 그중 몇 개가 강화됐다" 같은 설명은 Google 문서로 확인할 수 없는 추정입니다. 진단에서 이런 설명을 전제로 삼으면 실제 원인과 다른 방향으로 시간을 쓰게 됩니다.

Google 쪽에서도 이 값이 지금 형태로는 도움이 되지 않는다는 점을 인정한 바 있습니다. 2025년 12월 29일 Google AI 개발자 포럼에서 Nano Banana Pro 사용자가 요청 5건 중 1건꼴로 `OTHER`가 나온다고 올리자, Google의 Logan Kilpatrick은 "'Other' 오류를 처리하는 방식을 고치려고 팀과 논의 중이며, 지금 구조로는 도움이 되지 않는다"고 답하고 1월 첫 2주 안에 반영하겠다는 목표를 밝혔습니다([포럼 스레드](https://discuss.ai.google.dev/t/blockreason-other/113496)). 이후 해당 스레드에 추가 공지는 없고, 2026년 10월 4일 기준 API 참조의 정의도 여전히 "알 수 없는 이유"입니다.

## 세 가지 OTHER 구분: blockReason, finishReason, IMAGE_OTHER

응답에 `OTHER`라는 글자가 보인다고 모두 같은 상황은 아닙니다. JSON에서 어느 위치에 있는지에 따라 의미와 다음 조치가 다릅니다.

| 위치 | 후보 | Google 문서의 설명 | 먼저 볼 것 |
| --- | --- | --- | --- |
| `promptFeedback.blockReason: "OTHER"` | 없음 | 알 수 없는 이유로 프롬프트 차단 | 요청 내용과 조건, 아래 진단 순서 |
| `candidates[].finishReason: "OTHER"` | 있음 | 알 수 없는 이유(Unknown reason)로 생성 중단 | 같은 후보의 `finishMessage` |
| `candidates[].finishReason: "IMAGE_OTHER"` | 있음 | 기타 문제로 이미지 생성 중단 | 같은 후보의 `finishMessage` |

![응답 JSON에서 OTHER가 나오는 세 위치인 promptFeedback.blockReason, candidates의 finishReason OTHER와 IMAGE_OTHER를 후보 유무와 먼저 볼 것으로 비교한 그림](https://blog.laozhang.ai/posts/ko/nano-banana-2-blockreason-other/img/other-field-locations.webp)

프롬프트 단계에서 차단된 응답은 대략 이런 모양입니다. `candidates`가 아예 없거나 비어 있고, 이유는 `promptFeedback` 안에만 있습니다.

```json
{
  "promptFeedback": {
    "blockReason": "OTHER"
  }
}
```

실제 응답에는 여기에 `usageMetadata`, `modelVersion`, `responseId` 같은 최상위 필드가 함께 붙습니다. Python SDK(`google-genai`)에서는 같은 값을 `response.prompt_feedback.block_reason`으로 읽습니다.

반대로 `finishReason`은 후보가 만들어진 뒤 각 후보에 붙는 값입니다. `finishReason`이 채워져 있으면 `finishMessage`에 추가 설명이 들어 있을 수 있으니 그것부터 읽으세요. `NO_IMAGE`(이미지를 만들어야 했지만 만들지 않음), `IMAGE_SAFETY`, `IMAGE_PROHIBITED_CONTENT`처럼 후보는 있는데 이미지가 없는 경우, 그리고 HTTP 200인데 텍스트만 온 경우는 [Nano Banana API 이미지 안 나옴: 응답별 원인과 조치](https://blog.laozhang.ai/ko/posts/nano-banana-2-200-ok-no-image)에서 응답 형태별로 다룹니다.

Interactions API로 호출하고 있다면 응답에 `candidates`나 `promptFeedback`이 없고 `steps`와 `status`로 결과를 돌려주므로, 위 필드 이름은 그대로 적용되지 않습니다. 그 구조도 같은 글에서 다룹니다.

## blockReason OTHER가 나오면 저장할 증거 체크리스트

`OTHER`는 응답 자체에 원인이 없으므로, 나중에 원인을 좁히거나 Google에 물어볼 때 쓸 수 있는 것은 그 순간 남겨 둔 기록뿐입니다. 아래 항목은 API 참조에 문서화된 응답 필드와 요청 조건을 모은 것입니다. Google이 `OTHER` 문의용 필수 목록을 따로 공개하지는 않았지만, 포럼에서 Google 직원이 스크린샷과 세부 정보를 DM으로 요청한 사례가 있습니다(2026년 5월, 아래 사례 참고).

| 항목 | 저장하는 이유 |
| --- | --- |
| 원본 응답 JSON 전체 | SDK가 가공하기 전 원본이 있어야 실제 응답 문제와 파싱 오류를 구분할 수 있습니다 |
| `responseId` | 응답마다 붙는 식별자로, 문의할 때 특정 호출을 가리킬 수 있습니다 |
| `modelVersion`과 요청에 쓴 모델 ID | 어떤 모델 버전이 응답했는지 남깁니다 |
| `promptFeedback` 객체 전체 | `blockReason`과 함께 `safetyRatings`가 있으면 그대로 남깁니다 |
| 각 후보의 `finishReason`, `finishMessage` | 후보가 있을 때 프롬프트 차단과 생성 중단을 구분합니다 |
| `usageMetadata` | 과금 여부를 확인하는 근거입니다(아래 과금 항목 참고) |
| 요청 시각(UTC) | 특정 시간대에만 몰렸는지 볼 수 있습니다 |
| 참조 이미지 첨부 여부와 개수 | 이미지를 넣었을 때만 차단되는지 비교할 수 있습니다 |
| 응답 형식(`responseModalities`) 등 생성 설정 | 같은 프롬프트라도 설정이 다르면 비교가 무의미해집니다 |
| 프롬프트 원문과 첨부 이미지 | 재현에 필요합니다. 내부에만 보관하고, 외부에는 가린 사본만 공유합니다 |

프롬프트와 이미지에 고객 정보나 실존 인물 사진이 들어 있을 수 있으므로, 포럼처럼 공개된 곳에 올릴 때는 반드시 민감한 부분을 가린 사본을 쓰세요.

## 응답 점검 스크립트: OTHER를 성공이나 일시 오류로 처리하지 않기

코드에서 생기기 쉬운 실수는 두 가지입니다. `candidates[0]`부터 읽다가 후보가 없는 응답에서 예외가 나거나 빈 결과를 성공처럼 넘기는 것, 그리고 `OTHER`를 429·503 같은 일시 오류로 보고 무한 재시도하는 것입니다. 아래 Python 스크립트는 저장해 둔 `generateContent` 응답 JSON 하나를 읽어 다섯 가지 결과 중 하나로 분류합니다.

| `status` | 뜻 | 코드에서 할 일 |
| --- | --- | --- |
| `api_error` | 응답에 `error` 객체가 있음 | 오류 코드별 처리(429·503 등) |
| `prompt_blocked` | `blockReason`이 설정됨(`OTHER`, `SAFETY`, 앞으로 추가될 값 포함) | 증거 기록. 기본은 자동 재시도 없음 |
| `candidate_stopped` | 후보의 `finishReason`이 `STOP`이 아님 | `finishMessage` 확인, 기록 |
| `image_ready` | `finishReason`이 `STOP`인 후보에서 유효한 이미지를 찾음 | 저장 |
| `no_image` | 위 어디에도 해당하지 않고 이미지도 없음 | 이미지 안 나옴 가이드의 응답 형태별 점검 |

스크립트는 `thought` 파트를 건너뛰고, MIME 형식이 PNG·JPEG·WebP인지, base64가 정상적으로 디코딩되는지, 바이트가 비어 있지 않은지, Pillow로 실제 이미지를 열 수 있고 그 형식이 MIME과 일치하는지 확인합니다. `finishReason`이 `OTHER`인데 이미지가 붙어 있는 경우처럼 `STOP`이 아닌 후보의 이미지는 바로 쓰지 않고 검토 대상으로 남깁니다.

```python
import base64
import binascii
import io
import json
import sys
from pathlib import Path

from PIL import Image, UnidentifiedImageError

# 허용하는 MIME 형식과 Pillow가 판별하는 실제 형식의 대응
FORMATS = {"image/png": "PNG", "image/jpeg": "JPEG", "image/webp": "WEBP"}


def as_dict(value):
    return value if isinstance(value, dict) else {}


def as_list(value):
    return value if isinstance(value, list) else []


def inspect_response(response):
    if not isinstance(response, dict):
        raise ValueError("응답의 최상위는 JSON 객체여야 합니다")

    feedback = as_dict(response.get("promptFeedback"))
    block = feedback.get("blockReason")
    report = {
        "status": "no_image",
        "response_id": response.get("responseId"),
        "model_version": response.get("modelVersion"),
        "usage": response.get("usageMetadata"),
        "block_reason": block,
        "prompt_safety_ratings": as_list(feedback.get("safetyRatings")),
        "candidates": [],
        "images": [],
    }
    if response.get("error"):
        report["status"] = "api_error"
        return report
    # OTHER뿐 아니라 SAFETY나 앞으로 추가될 값도 프롬프트 차단으로 처리합니다.
    if block and block != "BLOCK_REASON_UNSPECIFIED":
        report["status"] = "prompt_blocked"
        return report

    candidates = as_list(response.get("candidates"))
    for ci, raw_candidate in enumerate(candidates):
        candidate = as_dict(raw_candidate)
        reason = candidate.get("finishReason")
        entry = {
            "index": ci,
            "finish_reason": reason,
            "finish_message": candidate.get("finishMessage"),
            "safety_ratings": as_list(candidate.get("safetyRatings")),
            "image_issues": [],
        }
        report["candidates"].append(entry)
        content = as_dict(candidate.get("content"))
        for pi, raw_part in enumerate(as_list(content.get("parts"))):
            part = as_dict(raw_part)
            # 사고 과정(thought) 파트의 이미지는 최종 결과물이 아니므로 건너뜁니다.
            if part.get("thought"):
                continue
            blob = as_dict(part.get("inlineData"))
            if not blob:
                continue
            mime = blob.get("mimeType")
            encoded = blob.get("data")
            problem = None
            data = b""
            if not isinstance(mime, str) or mime not in FORMATS:
                problem = "unsupported_mime"
            elif not isinstance(encoded, str) or not encoded:
                problem = "empty_or_missing_data"
            else:
                try:
                    data = base64.b64decode(encoded, validate=True)
                    if not data:
                        raise ValueError("empty bytes")
                    with Image.open(io.BytesIO(data)) as img:
                        actual_format = img.format
                        img.load()
                    if actual_format != FORMATS[mime]:
                        raise ValueError("MIME does not match image format")
                except (ValueError, binascii.Error, OSError,
                        UnidentifiedImageError, Image.DecompressionBombError):
                    problem = "invalid_image_data"
            if problem:
                entry["image_issues"].append({"part": pi, "reason": problem})
            # finishReason이 STOP인 후보의 이미지만 결과로 인정합니다.
            elif reason == "STOP":
                report["images"].append({
                    "candidate": ci, "part": pi, "mime_type": mime, "data": data
                })
            else:
                entry["image_issues"].append({
                    "part": pi, "reason": "finish_reason_requires_review"
                })

    if report["images"]:
        report["status"] = "image_ready"
    elif any(c["finish_reason"] not in (None, "STOP", "FINISH_REASON_UNSPECIFIED")
             for c in report["candidates"]):
        report["status"] = "candidate_stopped"
    return report


if __name__ == "__main__":
    response = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
    result = inspect_response(response)
    # 바이너리나 전체 로그는 터미널에 출력하지 않고 확인용 요약만 표시합니다.
    print(json.dumps({
        "status": result["status"],
        "block_reason": result["block_reason"],
        "finish_reasons": [c["finish_reason"] for c in result["candidates"]],
        "image_count": len(result["images"]),
        "image_issues": [c["image_issues"] for c in result["candidates"]],
    }, ensure_ascii=False, indent=2))
```

`inspect_response.py`로 저장하고 Pillow를 설치한 뒤, 저장해 둔 응답 파일을 넘겨 실행합니다.

```bash
pip install pillow
python3 inspect_response.py response.json
```

위의 프롬프트 차단 예시 JSON을 넣으면 다음과 같이 출력됩니다.

```json
{
  "status": "prompt_blocked",
  "block_reason": "OTHER",
  "finish_reasons": [],
  "image_count": 0,
  "image_issues": []
}
```

이 스크립트는 손으로 만든 응답 JSON 29가지에 대한 오프라인 테스트를 모두 통과합니다(Python 3.12.1, Pillow 12.0.0, 2026년 10월 4일 기준). 후보 누락·`null`·빈 배열, 텍스트만 있는 `STOP`, 프롬프트 단계의 `OTHER`·`SAFETY`·문서에 없는 새 값, 후보 단계의 `OTHER`·`NO_IMAGE`, 비었거나 잘못된 base64, 가짜 PNG, MIME 불일치, `thought` 이미지, 이미지가 붙은 `OTHER`, 두 번째 후보만 정상인 경우, `error` 객체 등이 포함됩니다. Gemini API를 실제로 호출한 테스트가 아니므로, 분기 처리가 의도대로 동작한다는 것만 보여 줄 뿐 Google이 언제 `OTHER`를 반환하는지에 대해서는 아무것도 증명하지 않습니다.

Python SDK 응답 객체를 REST와 같은 camelCase JSON 파일로 저장하는 방법은 [Nano Banana API 이미지 안 나옴: 응답별 원인과 조치](https://blog.laozhang.ai/ko/posts/nano-banana-2-200-ok-no-image)에 있습니다. 서비스 코드에서는 `prompt_blocked`를 받았을 때 사용자에게 "요청 내용 때문에 이미지를 만들 수 없었다"는 취지로 안내하고, 증거 체크리스트의 항목을 로그에 남긴 뒤 그 요청을 종료하는 흐름이 무난합니다. 자동 재시도를 둘지는 아래 판단 기준을 따릅니다.

## 원인 좁히기: 변수 하나만 바꿔 다시 보내는 순서

`OTHER`의 원인은 응답에 없으므로, 조건을 하나씩 바꿔 보며 어디서 결과가 갈리는지 관찰하는 수밖에 없습니다. 한 번에 두 가지를 바꾸면 무엇이 결과를 바꿨는지 알 수 없으니 반드시 하나씩 바꾸고, 시도마다 위 체크리스트대로 기록합니다.

1. **모델 ID부터 확인합니다.** Nano Banana 2는 `gemini-3.1-flash-image`, Nano Banana Pro는 `gemini-3-pro-image`입니다. `gemini-3.1-flash-image-preview`와 `gemini-3-pro-image-preview`는 2026년 6월 25일 종료되었습니다([Google 지원 중단 일정](https://ai.google.dev/gemini-api/docs/deprecations)). 예전 코드라면 이것부터 바꿉니다.
2. **완전히 같은 요청을 한 번만 다시 보냅니다.** 이번에는 통과한다면 같은 내용으로도 결과가 흔들리는 간헐적 차단이고, 다시 막힌다면 요청 조건과 관련된 차단으로 보고 다음 단계로 넘어갑니다. 앞서 소개한 2025년 12월 포럼 보고처럼 일정 비율로만 `OTHER`가 섞이는 사례가 있어 이 구분이 의미가 있습니다. 같은 요청을 그 이상 반복해도 원인에 대한 정보는 늘지 않습니다.
3. **참조 이미지를 빼고 텍스트만 보냅니다.** 이미지를 넣었을 때만 막힌다면 원인 후보는 첨부 이미지 쪽으로 좁혀집니다. 이미지가 여러 장이면 한 장씩 빼 봅니다.
4. **프롬프트에서 요소 하나만 뺍니다.** 실존 인물 이름, 특정 브랜드나 캐릭터, 특정 신체 묘사처럼 쟁점이 될 만한 요소를 하나씩 빼 보고 결과를 비교합니다. 어떤 요소를 뺐을 때 통과한다면 그 요소가 차단과 관련 있을 가능성이 높습니다.
5. **아주 평범한 프롬프트로 같은 키·프로젝트에서 호출해 봅니다.** "흰 배경 위의 빨간 사과"처럼 문제될 것이 없는 요청까지 `OTHER`로 막힌다면, 원인은 요청 내용보다 계정·프로젝트나 서비스 쪽에 있을 가능성이 커지므로 바로 문의 단계로 넘어갑니다.

4단계에서 특정 요소가 원인으로 보인다고 해서, 같은 대상을 다른 말로 돌려 표현해 통과시키려 해서는 안 됩니다. 그것은 원인 진단이 아니라 정책을 피해 가는 시도이고, 실제로 2026년 2월 Stack Overflow에 올라온 사례에서는 공인의 이름을 빼고 묘사로 바꿔 써도 계속 차단되었습니다. 요소가 특정되면 그 요소가 정말 필요한지, 사용 목적에 맞는 다른 소재로 바꿀 수 있는지를 판단해야 합니다. 같은 이유로 프록시나 다른 지역 서버를 거쳐 보내기, 요청을 여러 조각으로 나눠 보내기도 진단 방법이 아닙니다.

## 재시도할 때, 멈출 때, Google에 문의할 때

위 순서를 거친 결과에 따라 다음 행동이 달라집니다. 자동 재시도 횟수에 대한 Google의 공식 기준은 없으며, 아래 규칙은 필드 정의와 공개된 사례를 바탕으로 한 판단입니다.

| 관찰한 결과 | 판단 | 다음 행동 |
| --- | --- | --- |
| 같은 요청을 다시 보내니 통과 | 간헐적 차단 | 발생 빈도를 기록합니다. 이 경우에만 서비스 코드에 자동 재시도 1회를 둘 수 있습니다 |
| 같은 요청은 계속 막히고, 요소 하나를 빼면 통과 | 그 요소가 차단과 관련 | 소재나 사용 목적을 바꿉니다. 같은 대상을 우회 표현으로 다시 보내지 않습니다 |
| 참조 이미지를 넣을 때만 막힘 | 첨부 이미지 쪽 원인 가능성 | 다른 이미지로 비교하고, 정상적인 이미지인데도 계속 막히면 문의합니다 |
| 평범한 프롬프트까지 막힘, 또는 잘 되던 요청이 갑자기 전부 막힘 | 요청 내용 밖의 원인 가능성 | 더 바꿔 보지 말고 증거를 모아 문의합니다 |
| 변수를 다 바꿔도 결과가 일정하지 않음 | 좁혀지지 않음 | 시도를 멈추고 기록한 응답을 묶어 문의합니다 |

![변수 하나씩 바꿔 본 다섯 가지 결과별로 재시도 1회, 소재 변경, 이미지 비교, Google 문의 중 다음 행동을 정리한 판단표](https://blog.laozhang.ai/posts/ko/nano-banana-2-blockreason-other/img/retry-stop-contact.webp)

`prompt_blocked`를 기본적으로 자동 재시도하지 않는 이유는 세 가지입니다. 필드 설명이 제시하는 조치가 재시도가 아니라 "프롬프트를 바꿔 작성하라"이고, 같은 요청을 반복하면 결과가 바뀐다는 공개 규칙이 없으며, 차단된 호출의 과금 규칙도 공개되어 있지 않기 때문입니다. 429나 503처럼 기다리면 풀리는 오류와는 성격이 다릅니다. 그런 오류의 재시도 간격과 처리 방법은 [Nano Banana API 오류 해결: 429, 503, 이미지 없음, 요청 거부](https://blog.laozhang.ai/ko/posts/nano-banana-pro-error)와 [Nano Banana 2 503 "Model is Overloaded" 오류 해결: 검증된 6가지 솔루션 (2026)](https://blog.laozhang.ai/ko/posts/nano-banana-2-503-overloaded-fix)을 참고하세요.

문의는 [Google AI 개발자 포럼](https://discuss.ai.google.dev/)이 공개된 창구입니다. 저장한 `responseId`, `modelVersion`, 요청 시각(UTC), 모델 ID, 참조 이미지 여부, 그리고 위 진단 순서에서 바꾼 변수와 그때마다의 결과를 함께 적으면, 같은 질문을 여러 번 주고받지 않아도 됩니다. 프롬프트와 이미지는 민감한 부분을 가린 사본만 올립니다.

## BLOCK_NONE으로 blockReason OTHER가 풀리나요

기대하기 어렵습니다. [Google 안전 설정 문서](https://ai.google.dev/gemini-api/docs/safety-settings)에 따르면 `generateContent`에서 조정할 수 있는 것은 괴롭힘, 증오 표현, 성적으로 노골적인 콘텐츠, 위험한 콘텐츠 네 범주의 임계값입니다. 아동 안전을 위협하는 콘텐츠 같은 핵심 위해에 대한 기본 보호는 항상 차단되며 조정할 수 없습니다. 또한 Gemini 2.5와 3 계열 모델은 임계값을 지정하지 않으면 기본값이 이미 `OFF`입니다.

`OTHER`가 이 네 범주 중 어디에도 연결되어 있다는 문서가 없으므로, `BLOCK_NONE`이나 `OFF`로 바꿔도 `OTHER`가 사라진다고 기대할 근거가 없습니다. 이것은 문서에서 끌어낸 추론이지만 관찰과도 맞습니다. 2026년 2월 6일 [Stack Overflow 질문](https://stackoverflow.com/questions/79884545)에서는 `gemini-3-pro-image-preview`로 공인 관련 이미지를 요청했을 때 모든 범주를 `BLOCK_NONE`으로 두어도 `blockReason: OTHER`가 계속 나왔습니다. 안전 설정을 바꿔서 결과가 달라지는 것은 `blockReason`이 `SAFETY`이고 `safetyRatings`가 조정 가능한 범주를 가리킬 때입니다.

## 개발자 보고로 본 blockReason OTHER 발생 상황

아래는 공개 포럼과 Q&A 사이트에 올라온 개별 보고입니다. 대부분 Nano Banana Pro와 지금은 종료된 preview ID에서 나온 것이고, 원인을 증명하지는 않습니다. 이런 상황에서도 `OTHER`가 나올 수 있다는 관찰로만 참고하세요.

- **평범해 보이는 요청이 일정 비율로 막힘**(2025년 12월 29일, [Google AI 개발자 포럼](https://discuss.ai.google.dev/t/blockreason-other/113496)): Google AI Studio를 통해 Nano Banana Pro API를 쓰는 웹 서비스에서 요청 5건 중 1건꼴로 결과 없이 `OTHER`가 기록되었다는 보고입니다. Google 측 답변은 앞에서 소개한 대로 "지금 구조로는 도움이 되지 않는다"였습니다.
- **참조 이미지를 넣으면 매번 막힘**(2026년 5월 7일, [Google AI 개발자 포럼](https://discuss.ai.google.dev/t/persistent-other-block-reason-error-on-nano-banana-pro-gemini-3-pro-image-preview-with-reference-images/143901)): Google AI Studio에서 `gemini-3-pro-image-preview`에 참조 이미지를 첨부할 때마다 'Other' 차단 사유로 막힌다는 보고입니다. Google 직원이 세부 정보를 DM으로 요청했고, 공개된 해결 내용은 없습니다.
- **공인 이름이 들어간 요청이 BLOCK_NONE에서도 막힘**(2026년 2월 6일, Stack Overflow): 이름 대신 묘사로 바꿔도 차단되었습니다. 댓글에 "지역 규제가 아니라 실존 인물 생성 정책 때문"이라는 주장이 있지만 근거가 제시되지 않았고, 다른 지역 서버를 거치라는 답변은 검증되지 않은 우회 방법이라 따를 이유가 없습니다.

세 사례 모두 "어떤 조건에서 나왔는가"는 알려 주지만 "왜 나왔는가"는 알려 주지 않습니다. 자신의 요청을 진단할 때 출발점으로 삼을 수는 있어도, 이것을 Google의 규칙처럼 일반화하면 안 됩니다.

## OTHER로 차단된 호출도 과금되나요: usageMetadata로 확인

Google은 `blockReason`으로 차단되어 후보가 없는 호출이 이미지 요금으로 과금된다는 규칙도, 무료라는 규칙도 공개하지 않았습니다. 그러니 "차단되면 과금되지 않는다"거나 "전액 과금된다"고 가정하지 말고 실제 호출로 확인해야 합니다.

확인 방법은 두 가지입니다. 하나는 해당 응답의 `usageMetadata`로, `promptTokenCount`(입력), `candidatesTokenCount`(출력), `thoughtsTokenCount`(사고 과정) 값이 어떻게 기록되었는지 봅니다. 다른 하나는 결제 보고서에서 같은 시간대의 사용량을 대조하는 것입니다. 차단 응답이 반복되는 서비스라면 며칠 치 로그와 결제 내역을 맞춰 보면 실제 비용 영향이 드러납니다.

API 게이트웨이를 거쳐 호출한다면 Google 규칙이 아니라 게이트웨이의 과금 규칙이 적용되므로 그 문서와 호출 로그를 따로 확인하세요. 예를 들어 [LaoZhang API 문서](https://docs.laozhang.ai/en/api-capabilities/nano-banana-image)는 이미지 없이 끝난 HTTP 200 응답을 1회 호출로 과금한다고 적고 있습니다(2026년 10월 4일 기준).

*안내: [laozhang.ai는 이 블로그 운영팀의 자사 서비스입니다](https://blog.laozhang.ai/ko/about#laozhang). 그 가격은 독립적인 비교가 아니라 자사 제시 가격입니다.*

## blockReason OTHER 관련 자주 묻는 질문

### blockReason OTHER는 지역 때문에 생기나요?

Google은 `OTHER`가 호출 지역에 따라 달라진다는 정보를 공개하지 않았습니다. Stack Overflow 댓글에 지역 문제가 아니라는 주장이 있지만 근거는 없습니다. 지역을 바꿔 보는 것은 원인을 밝히는 방법이 아니라 제공자의 통제를 피해 가는 시도가 될 수 있으니, 진단은 위의 변수 하나씩 바꾸기 순서로 하고 결론이 나지 않으면 Google에 문의하세요.

### Nano Banana Pro에서도 blockReason OTHER 의미가 같나요?

같습니다. `BlockReason`은 `generateContent` 응답 공통 필드이고, `OTHER`의 정의는 모델과 관계없이 "알 수 없는 이유로 프롬프트가 차단됨"입니다. 공개된 개발자 보고는 대부분 Nano Banana Pro에서 나왔지만, 두 모델의 차단 기준이 어떻게 다른지는 공개되어 있지 않습니다.

### Interactions API에서도 blockReason OTHER가 나오나요?

`promptFeedback.blockReason`이라는 필드로는 나오지 않습니다. Interactions API 응답은 `candidates`와 `promptFeedback` 대신 `steps`와 `status`로 결과를 돌려주기 때문입니다. 사용자 지정 안전 설정도 Interactions API에서는 지원되지 않습니다. 응답 구조별 확인 방법은 [Nano Banana API 이미지 안 나옴: 응답별 원인과 조치](https://blog.laozhang.ai/ko/posts/nano-banana-2-200-ok-no-image)를 보세요.

### Gemini 앱에서 이미지가 안 나오는 것도 같은 문제인가요?

Gemini 앱이나 웹에서는 `blockReason` 같은 응답 필드를 볼 수 없고, 원인과 확인 순서도 API와 다릅니다. 앱 사용자는 [Gemini에서 Nano Banana Pro가 안 될 때는 앱 경로부터 확인하세요](https://blog.laozhang.ai/ko/posts/nano-banana-pro-not-working-in-gemini)를 참고하세요. 멀티턴 편집 중 `MISSING_THOUGHT_SIGNATURE`로 실패한다면 [Nano Banana 2 Thought Signature 오류: 모든 시나리오 완벽 수정 가이드 (2026)](https://blog.laozhang.ai/ko/posts/nano-banana-2-thought-signature-error)가 해당합니다.

### Google이 OTHER를 더 자세한 사유로 바꿀 계획이 있나요?

2025년 12월 포럼에서 Google의 Logan Kilpatrick이 'Other' 오류를 더 명확하게 고치겠다고 밝힌 적은 있습니다. 다만 2026년 10월 4일 기준 API 참조의 `OTHER` 정의는 여전히 "알 수 없는 이유"이고, 해당 포럼 스레드에도 이후 공지가 올라오지 않았습니다. 그때까지는 응답에 원인이 담겨 있지 않다는 전제로 증거를 남기고 진단하는 것이 현실적입니다.

## 참고 자료

이 글이 링크한 외부 페이지를 본문에 나온 순서대로 정리했습니다. 마지막 업데이트: 2026-10-04.

- [GenerateContent API 참조](https://ai.google.dev/api/generate-content) (ai.google.dev)
- [포럼 스레드](https://discuss.ai.google.dev/t/blockreason-other/113496) (discuss.ai.google.dev)
- [Google 지원 중단 일정](https://ai.google.dev/gemini-api/docs/deprecations) (ai.google.dev)
- [Google AI 개발자 포럼](https://discuss.ai.google.dev/) (discuss.ai.google.dev)
- [Google 안전 설정 문서](https://ai.google.dev/gemini-api/docs/safety-settings) (ai.google.dev)
- [Stack Overflow 질문](https://stackoverflow.com/questions/79884545) (stackoverflow.com)
- [Google AI 개발자 포럼](https://discuss.ai.google.dev/t/persistent-other-block-reason-error-on-nano-banana-pro-gemini-3-pro-image-preview-with-reference-images/143901) (discuss.ai.google.dev)
