최근 고객분들이 Nano Banana Pro(모델 ID: gemini-3-pro-image-preview)를 사용하여 이미지-이미지 변환을 호출할 때, 매우 "구글스러운" 400 에러를 겪는 경우가 종종 있습니다.
{
"status_code": 400,
"error": {
"message": "Unsupported file URI type: {{ $json.imageUrls }}. File URI must be a File API (e.g. https://generativelanguage.googleapis.com/files/<id>), Youtube (e.g. https://www.youtube.com/watch?v=<id>), or HTTPS (e.g. http://path/to/file).), or a valid gURI (e.g. gs://bucket/object",
"type": "",
"code": 400
}
}
이 Nano Banana Pro 에러 메시지는 사실 "범인"을 명확히 지목하고 있습니다. 바로 Unsupported file URI type: {{ $json.imageUrls }} 부분이죠. 여기서 {{ $json.imageUrls }}는 렌더링되지 않은 n8n 템플릿 변수 원문입니다. 즉, 고객이 워크플로우에 동적 표현식을 작성했지만, 엔진이 이를 실제 URL로 변환하지 않고 문자열 그대로 Gemini API의 fileUri 필드에 밀어 넣은 것입니다. 구글 입장에서는 {{ ... }} 형태의 URI를 인식할 수 없으니 요청을 거부한 것이죠.
본 글에서는 이 실제 에러 사례와 gemini-3-pro-image-preview의 공식 입력 형식 요구사항을 바탕으로, 가장 흔히 발생하는 5가지 시나리오를 분석하고 각각에 대한 최소 재현 코드와 즉각적인 해결책을 제시합니다. 이 글을 읽고 나면 5분 안에 Unsupported file URI type 에러가 발생하는 모든 요청을 찾아내고 수정할 수 있게 될 것입니다.

Nano Banana Pro 에러 핵심 정보 요약
코드를 수정하기 전에, 이번 에러의 핵심 정보와 구글이 허용하는 입력 URI 형식을 한눈에 확인해 보겠습니다.
| 구분 | 핵심 내용 |
|---|---|
| 모델 ID | gemini-3-pro-image-preview(Gemini API 내 Nano Banana Pro 정식 명칭) |
| 에러 HTTP 상태 | 400(Bad Request, 클라이언트 파라미터 오류) |
| 에러 핵심 필드 | Unsupported file URI type |
| 실제 문제 위치 | 요청 본문(body)의 fileData.fileUri 필드 |
| 에러 메시지 내 리터럴 | {{ $json.imageUrls }}(렌더링되지 않은 n8n 표현식) |
| Gemini 허용 URI 유형 | File API URI / YouTube URL / 공용 HTTPS URL / GCS gs:// URI |
| Gemini 허용 이미지 형식 | JPEG, JPG, PNG, WEBP, HEIF |
| Nano Banana Pro 외부 URL 지원? | ✅ 지원(Gemini 2.5+ 모델부터 공용 HTTPS / 사전 서명된 URL 기본 지원) |
| 주요 원인 | n8n / Make / Zapier 등 로우코드 워크플로우의 템플릿 변수 미치환 |
🎯 빠른 문제 해결 팁: 고객이 전체 요청 본문을 보여주기 꺼려한다면, APIYI(apiyi.com) 콘솔에서 동일한
gemini-3-pro-image-preview모델과 동일한 참조 이미지를 사용하여 성공적인 호출을 먼저 수행하게 하세요. 그 후 실패한 요청과 성공한 요청의 본문을 비교(diff)하는 것이 Nano Banana Pro 에러를 가장 빠르게 해결하는 방법입니다.
Nano Banana Pro의 Unsupported file URI type 오류 5가지 원인
실제 사례들을 분석해 본 결과, Unsupported file URI type 오류는 5가지 대표적인 원인으로 압축됩니다. 발생 빈도가 높은 순서대로 정리해 드릴게요.
원인 1: n8n / Make / Zapier의 템플릿 변수가 렌더링되지 않음
이 오류의 가장 유력한 용의자입니다. {{ $json.imageUrls }}는 n8n의 표현식 문법인데, 정상적이라면 실행 전 이전 노드에서 출력된 실제 URL(예: https://cdn.example.com/uploads/abc.jpg)로 치환되어야 합니다. 하지만 다음과 같은 경우 치환에 실패합니다.
- HTTP Request 노드의 Body 필드가 "Expression" 모드가 아닌 "Fixed" 모드로 설정되어, JSON 전체가 단순 텍스트 문자열로 전송됨.
- JSON Body에 이중 따옴표가 중첩되어, n8n이 표현식을 문자열의 일부로 오해하고 렌더링을 건너뜀.
- 이전 노드의 출력 구조와 작성한 경로가 일치하지 않음—예를 들어 실제 출력은
imageUrl(단수)인데$json.imageUrls(복수)로 작성하여 해석 실패 후 원문이 반환됨. - Sub-node의 표현식이 Item 단위로 반복되지 않고 첫 번째 항목만 고정적으로 가져오다가, 특정 입력값에서
undefined가 되어 문자열로 직렬화됨.
판단 방법: Gemini 오류 메시지에 {{ ... }}가 포함되어 있다면 100% 이 문제입니다. 정상적인 URL은 저런 형태일 수 없으니까요.
원인 2: 필드명 오타로 인한 undefined / null 전달
그다음으로 흔한 원인은 필드명 문제입니다. 고객의 코드에서 자주 발견되는 사례입니다.
// 상위 인터페이스에서 실제로 반환하는 필드명은 imageUrl(단수)
const upstream = { imageUrl: "https://cdn.example.com/a.jpg" };
// 하지만 하위 코드에서는 imageUrls(복수, s 포함)로 작성함
fileUri: upstream.imageUrls // 결과는 undefined
undefined는 JSON 직렬화나 문자열 결합 시 "undefined"라는 문자열로 변하는데, Gemini는 이를 인식하지 못합니다. 템플릿 변수 미렌더링과 거의 동일한 400 오류를 발생시키지만, 오류 메시지에 {{ ... }} 대신 undefined가 찍힌다는 점이 다릅니다.
원인 3: 배열을 문자열로 착각하여 fileUri에 전달
이 원인은 "여러 장의 이미지를 일괄 처리"할 때 자주 발생합니다. Gemini API의 fileData.fileUri 필드는 단일 문자열만 허용하며 배열은 받을 수 없습니다. 하지만 많은 개발자가 다음과 같이 작성하곤 합니다.
// ❌ 오류: 배열을 그대로 fileUri에 넣음
{
"fileData": {
"fileUri": ["https://cdn.example.com/a.jpg", "https://cdn.example.com/b.jpg"],
"mimeType": "image/jpeg"
}
}
JSON 직렬화 후 fileUri 필드가 ["https://...", "https://..."]라는 문자열이 되어 Gemini가 해석에 실패하고 Unsupported file URI type 오류를 냅니다. 올바른 방법은 배열을 fileUri에 넣는 것이 아니라, 각 이미지마다 별도의 parts 요소를 생성하는 것입니다.
원인 4: 지원되지 않는 URL 프로토콜 또는 경로 형식
네 번째는 "형식 불일치" 문제입니다. Gemini API가 허용하는 URI 유형은 4가지뿐이며, 범위를 벗어나는 모든 형식은 동일한 오류를 유발합니다.
| URI 유형 | 예시 | gemini-3-pro-image-preview 지원 여부 |
|---|---|---|
| File API 경로 | https://generativelanguage.googleapis.com/files/abc123 |
✅ |
| YouTube URL | https://www.youtube.com/watch?v=xxxxx |
✅(주로 영상 이해용) |
| 공용 HTTPS URL | https://cdn.example.com/img.jpg |
✅(Gemini 2.5+부터 기본 지원) |
GCS gs:// URI |
gs://my-bucket/img.jpg |
✅(Vertex AI 경로) |
http:// 일반 텍스트 |
http://cdn.example.com/img.jpg |
⚠️ 일부 거부됨, HTTPS 권장 |
file:// 로컬 경로 |
file:///Users/me/a.jpg |
❌ |
data:image/...;base64, |
base64 dataURL | ❌(inlineData 사용 권장) |
| Pre-signed S3 URL | https://bucket.s3.amazonaws.com/...?X-Amz-... |
✅ |
| Azure SAS URL | https://account.blob.core.windows.net/...?sv=... |
✅ |
로컬 파일 경로, data:로 시작하는 base64, 혹은 사설망 URL을 fileUri에 넣으면 예외 없이 Nano Banana Pro 오류가 발생합니다.
원인 5: URL은 유효하나 권한 부족 또는 이미지 미반환
마지막은 "URL은 맞지만 Gemini가 내용을 가져올 수 없는" 경우입니다. 흔한 사례는 다음과 같습니다.
- 사설 OSS / Qiniu / Cloudinary 링크의 공개 권한이 없어 Gemini가 403 오류를 받음.
- 임시 서명 URL이 만료됨.
- URL이 이미지가 아닌 HTML 페이지(예: 이미지 호스팅 사이트의 '공유 페이지')를 반환함.
- URL이 로그인 페이지로 리다이렉트됨.
- MIME 타입이
mimeType필드와 일치하지 않음.
이런 문제도 Unsupported file URI type으로 나타나거나 400 Invalid or unsupported file uri로 표시되기도 합니다. 해결 방법은 간단합니다. 브라우저의 시크릿 모드에서 해당 URL에 직접 접속하여 실제 이미지 파일이 다운로드되는지 확인하는 것이 가장 확실합니다.

Nano Banana Pro 오류의 최소 재현 및 즉시 해결 가이드
앞서 5가지 주요 원인을 살펴보았으니, 이제 각 상황별 최소 재현 코드와 해결 버전을 알려드릴게요. 이 코드를 그대로 복사해서 여러분의 워크플로우나 백엔드에 적용해 보세요.
해결 1: n8n에서 imageUrls 매개변수 올바르게 전달하기
고객이 겪고 있는 Nano Banana Pro 오류가 n8n의 HTTP Request 노드에서 발생한다면, 다음과 같이 작성하는 것이 올바른 방법입니다.
HTTP Request 노드 설정:
- Method:
POST - URL:
https://api.apiyi.com/v1/messages(APIYI API 중계 주소로 대체하세요) - Authentication: Header Auth(API 키 입력)
- Body Content Type:
JSON - Specify Body:
Using JSON선택(Using Fields 아님) - JSON Body(전체 JSON을 표현식 모드로 설정하세요. 왼쪽 보라색 fx 버튼을 클릭해야 합니다):
={
"model": "gemini-3-pro-image-preview",
"contents": [
{
"parts": [
{ "text": "이 이미지를 미야자키 하야오 스타일로 바꿔줘" },
{
"fileData": {
"fileUri": "{{ $json.imageUrls }}",
"mimeType": "image/jpeg"
}
}
]
}
]
}
핵심 포인트 3가지:
- JSON 문자열 앞에
=기호를 붙여 n8n에게 이 전체가 표현식임을 알려야 합니다. "{{ $json.imageUrls }}"외부에는 반드시 큰따옴표를 사용해야 내부의{{ }}가 실제 문자열로 치환됩니다.- 이전 노드에서 반드시
imageUrls라는 필드가 출력되어야 합니다. 만약imageUrl(단수)이나image_url로 출력된다면 필드명을 그에 맞춰 수정하세요.
이 3가지만 지키면 Unsupported file URI type 오류는 즉시 사라집니다.
해결 2: Python / Node.js에서 필드명 오타 방지
백엔드 코드를 사용 중이라면 입력 검증(Input Validation) 단계를 추가하여 Gemini에 요청을 보내기 전에 오타를 미리 잡아내는 것을 추천합니다.
import requests
def call_nano_banana_pro(prompt: str, image_url: str):
# 방어적 검증: 요청 전 None / 빈 문자열 / 템플릿 문자열을 미리 차단
if not image_url or not isinstance(image_url, str):
raise ValueError(f"image_url은 비어있지 않은 문자열이어야 합니다. 현재 값: {image_url!r}")
if image_url.startswith("{{") or "undefined" in image_url:
raise ValueError(f"image_url이 렌더링되지 않은 템플릿 변수 같습니다: {image_url}")
if not image_url.startswith(("https://", "gs://")):
raise ValueError(f"image_url은 https:// 또는 gs://로 시작해야 합니다: {image_url}")
payload = {
"model": "gemini-3-pro-image-preview",
"contents": [{
"parts": [
{"text": prompt},
{"fileData": {
"fileUri": image_url,
"mimeType": "image/jpeg"
}}
]
}]
}
resp = requests.post(
"https://api.apiyi.com/v1/messages",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json=payload,
timeout=120
)
return resp.json()
이런 "검증 후 전송" 방식을 사용하면 Nano Banana Pro 오류의 90%를 호출 전에 차단하여 Gemini 측의 실패 로그가 오염되는 것을 막을 수 있습니다.
해결 3: 여러 장의 이미지를 올바르게 parts로 분리하기
Nano Banana Pro에 여러 장의 참조 이미지를 전달해야 할 경우(예: 스타일 변환 + 인물 고정), 배열을 fileUri에 넣는 것이 아니라 각 이미지마다 별도의 parts 요소를 만들어야 합니다.
// ✅ 올바른 작성법
const imageUrls = [
"https://cdn.example.com/style.jpg",
"https://cdn.example.com/person.jpg"
];
const payload = {
model: "gemini-3-pro-image-preview",
contents: [{
parts: [
{ text: "두 번째 이미지의 인물을 첫 번째 이미지 스타일로 그려줘" },
...imageUrls.map(url => ({
fileData: { fileUri: url, mimeType: "image/jpeg" }
}))
]
}]
};
const resp = await fetch("https://api.apiyi.com/v1/messages", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_KEY"
},
body: JSON.stringify(payload)
});
이렇게 하면 Unsupported file URI type 오류를 피할 수 있을 뿐만 아니라, Gemini가 이미지 간의 의미 관계를 정확히 이해하게 됩니다.
해결 4: 접근 불가능한 URL은 base64 인라인으로 대체
사용 중인 URL이 프라이빗 버킷, 내부망 주소 또는 임시 URL이라 Gemini 서버에서 접근할 수 없는 경우가 있습니다. 이럴 때는 inlineData + base64 방식을 사용하는 것이 가장 확실합니다.
import base64
import requests
def call_with_base64(prompt: str, local_path: str):
with open(local_path, "rb") as f:
b64 = base64.b64encode(f.read()).decode("utf-8")
payload = {
"model": "gemini-3-pro-image-preview",
"contents": [{
"parts": [
{"text": prompt},
{"inlineData": {
"mimeType": "image/jpeg",
"data": b64
}}
]
}]
}
return requests.post(
"https://api.apiyi.com/v1/messages",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json=payload
).json()
참고: inlineData는 data 필드(순수 base64, data:image/jpeg;base64, 접두사 제외)를 사용하고, fileData는 fileUri 필드를 사용합니다. 둘은 상호 배타적이므로 동시에 입력하지 마세요.
🎯 안정성 제안: URL 출처가 불분명한 경우(예: 고객 업로드 / 타사 API)에는 이미지-이미지 변환 시 base64 인라인 방식을 기본으로 사용하고, APIYI(apiyi.com)와 같은 중계 플랫폼을 통해
gemini-3-pro-image-preview를 호출하는 것을 권장합니다. 네트워크나 권한 문제로 인한 외부 URL 거부 오류를 방지할 수 있습니다.
Nano Banana Pro 오류 점검 체크리스트
위 내용을 "5분 점검" 리스트로 요약했습니다. Unsupported file URI type 오류 발생 시 바로 확인해 보세요.
5분 점검 체크리스트
| 단계 | 동작 | 기대 결과 |
|---|---|---|
| 1 | 오류 메시지의 Unsupported file URI type: 뒤에 있는 값을 복사 |
Gemini가 실제로 수신한 fileUri 값 확인 |
| 2 | 값이 {{、undefined、null、[ 등을 포함하는지 확인 |
포함 시 → 90%는 템플릿 미렌더링 또는 필드명 오류 |
| 3 | 브라우저 시크릿 창에서 해당 URL을 직접 열어보기 | 기대 결과: 유효한 JPEG/PNG/WEBP 이미지 다운로드 가능 |
| 4 | URL 프로토콜이 https:// 또는 gs://인지 확인 |
아닐 경우 → 프로토콜 수정 또는 base64로 변경 |
| 5 | 프라이빗 버킷, 만료된 서명, 리다이렉트 여부 확인 | 해당 시 → 공용 URL로 변경 또는 base64로 변경 |
| 6 | APIYI apiyi.com 콘솔에서 동일 모델 + 공개 이미지로 재현 | 성공 시 → 클라이언트 문제; 실패 시 → 당사에 문의 |
이 6단계를 거치면 Nano Banana Pro 오류의 근본 원인을 대부분 찾아낼 수 있습니다.
Nano Banana Pro Unsupported file URI type 자주 묻는 질문(FAQ)
Q1: 왜 에러 메시지에 {{ $json.imageUrls }}라는 리터럴 문자열이 그대로 찍히나요?
Gemini API는 요청을 받을 때 fileUri 필드 값을 에러 메시지에 그대로 포함합니다. 이는 Google의 표준 동작으로, "도대체 무엇을 보냈는가?"를 빠르게 파악하도록 돕기 위함입니다. 만약 {{ ... }}와 같은 리터럴이 보인다면, 이는 100% 로우코드 워크플로우의 템플릿 변수가 렌더링되지 않은 것입니다. 만약 undefined나 null이 보인다면 필드명 오타일 가능성이 높습니다. 먼저 APIYI(apiyi.com)에서 실제 공용 URL을 사용하여 호출이 성공하는지 확인한 뒤, 클라이언트 설정을 그에 맞춰 수정하는 것을 권장합니다.
Q2: Nano Banana Pro / gemini-3-pro-image-preview는 어떤 URL을 지원하나요?
Google 공식 문서에 따르면 fileUri는 4가지 유형의 URI를 지원합니다: File API 경로(https://generativelanguage.googleapis.com/files/...), YouTube URL(주로 영상 이해용), 공용 HTTPS URL(S3 Pre-signed, Azure SAS 포함), GCS gs:// URI. Gemini 2.5 이상 모델은 공용 HTTPS를 기본 지원하므로, gemini-3-pro-image-preview는 이미지를 File API에 먼저 업로드할 필요가 없습니다.
Q3: n8n에서 {{ $json.imageUrls }}가 렌더링되지 않으면 어떻게 하나요?
가장 흔한 해결책 3가지는 다음과 같습니다. 첫째, HTTP Request 노드의 JSON Body에서 표현식(Expression) 모드가 활성화되어 있는지 확인하세요(JSON 전체 앞에 = 기호가 있거나 왼쪽 fx 버튼이 켜져 있어야 합니다). 둘째, 필드 경로가 이전 노드의 실제 출력값과 일치하는지 확인하세요. n8n의 "Execute Node" 이후 Output 패널에서 필드명을 직접 확인할 수 있습니다. 셋째, 서브 노드를 사용하는 경우 표현식은 기본적으로 첫 번째 항목만 가져옵니다. 메인 노드를 사용하거나 Item Lists 노드를 통해 데이터를 먼저 펼쳐야 합니다.
Q4: 에러에 undefined라고 나오면 어떻게 고치나요?
코드에서 존재하지 않는 필드에 접근했다는 뜻입니다. 가장 빠른 해결책은 Gemini를 호출하기 전에 assert image_url is not None and isinstance(image_url, str)와 같은 단언문을 추가하는 것입니다. 그 후 상위 인터페이스의 반환값에서 필드명을 확인하세요. imageUrls vs imageUrl, image_url vs imageUrl, url vs uri와 같은 오타가 흔합니다. 프로덕션 환경에서는 본문의 "수정 2" 파이썬 코드처럼 "https/gs가 아닌" 문자열을 요청 단계에서 미리 차단하는 것이 좋습니다.
Q5: 여러 장의 이미지를 fileUri에 한꺼번에 넣을 수 있나요?
아니요. fileUri는 단일 문자열만 허용합니다. 여러 장의 이미지를 보내려면 각 이미지마다 { "fileData": { "fileUri": "...", "mimeType": "..." } } 요소를 생성하여 동일한 parts 배열에 담아야 합니다. 그래야 Gemini가 이미지 간의 의미 관계를 올바르게 인식할 수 있습니다.
Q6: 비공개 버킷이나 임시 서명 URL을 공개할 수 없는 상황이라면요?
가장 확실한 방법은 inlineData + base64를 사용하는 것입니다. 이미지를 직접 읽어 base64로 인코딩한 뒤 요청 본문에 넣는 방식입니다. 이렇게 하면 Gemini 서버가 외부 리소스를 가져올 필요가 없으므로 "인증 실패 / 서명 만료 / MIME 불일치" 문제를 모두 피할 수 있습니다. 단, 요청 본문이 커지므로 작은 크기의 단일 이미지에 적합합니다. 고성능 이미지 생성(이미지-이미지 변환)이 필요하다면, 이미지를 먼저 공용 CDN에 업로드한 뒤 APIYI(apiyi.com)를 통해 gemini-3-pro-image-preview를 호출하는 것을 추천합니다. 이렇게 하면 base64로 인한 용량 증가를 막고 플랫폼 차원의 캐싱과 재시도 기능을 활용할 수 있습니다.

요약: Nano Banana Pro 에러 수정 후 모범 사례
고객의 구체적인 Nano Banana Pro 에러인 Unsupported file URI type: {{ $json.imageUrls }}로 돌아가 보면, 이는 Gemini의 문제가 아니라 n8n/로우코드 워크플로우가 템플릿 변수를 실제 URL로 치환하지 못해 {{ ... }} 리터럴이 그대로 Gemini API로 전달된 것임을 확실히 알 수 있습니다. 해결 방법은 본문의 "수정 1"에 제시된 대로 HTTP Request 노드의 JSON Body에서 표현식 모드를 켜고, 이전 노드에서 imageUrls 필드가 실제로 출력되는지 확인하는 것입니다.
더 넓은 관점에서 Unsupported file URI type 에러는 많은 팀이 이미지 API를 호출할 때 "입력 검증" 단계가 부족하다는 점을 보여줍니다. 이로 인해 Gemini가 요청을 거부할 때 모델 문제인지, 네트워크 문제인지, 파라미터 문제인지 파악하기 어렵습니다. 본문에서 제공한 5분 체크리스트, 파이썬 검증 코드, n8n 표현식 작성법을 팀의 표준 대응 프로세스로 활용해 보세요.
🎯 최종 제안: gemini-3-pro-image-preview 기반의 이미지 생성 워크플로우를 구축 중이라면, 모든 Nano Banana Pro 호출을 APIYI(apiyi.com)와 같은 API 중계 서비스로 통합하는 것을 권장합니다. 이를 통해 콘솔에서 실패한 요청을 빠르게 재현 및 비교할 수 있고, Google 자체 장애 발생 시 Nano Banana 2 / Seedream 등 동급 모델로 원활하게 전환할 수 있어 Unsupported file URI type과 같은 파라미터 오류를 즉시 파악하고 수정할 수 있습니다.
작성자: APIYI Team | AI 대규모 언어 모델 도입 및 안정성 엔지니어링에 집중합니다. 더 많은 Gemini 및 이미지 API 실전 트러블슈팅은 APIYI(apiyi.com)를 방문해 주세요.
