CATEGORY

카테고리 (689)
AI (87)
Language & Specs (260)
FrameWork (36)
Library (20)
App (41)
Git (10)
Build & Dependency (2)
AWS (15)
DataBase (45)
OS (33)
Tool (17)
IT (120)
SEEMINGLY ONLINE

Seemingly
Online

이모저모 방방곡곡 두루두루 개발지식 저장소

RECENT POSTS

AI/Gemini

gemini api 503 에러 — 과부하 원인과 재시도 설정

반응형

Gemini API의 503 에러(UNAVAILABLE)는 내 키나 한도 문제가 아니라 구글 서버가 잠깐 과부하이거나 내려가 있다는 뜻입니다. 공식 대응은 잠깐 기다렸다가 간격을 늘려 가며 재시도하는 것입니다. 그런데 파이썬 SDK google-genai 2.33.0을 직접 돌려 보면 기본 설정에서는 503을 재시도하지 않고 첫 실패에서 바로 ServerError를 던집니다. HttpRetryOptions를 넣어야 재시도가 켜집니다. 아래는 2026년 10월 23일 공식 문서를 원문으로 확인하고, 예제는 SDK에 가짜 서버를 붙여 그대로 실행해 본 결과입니다.

1. gemini api 503 unavailable 뜻 — 429·500·504와 차이

에러 응답에는 "code": 503, "status": "UNAVAILABLE"가 오고, 메시지는 The model is overloaded. Please try again later.나 high demand가 들어간 문구로 많이 검색됩니다. 공식 API 에러 표에서 비슷한 코드와 나란히 놓으면 이렇습니다.

코드 뜻 공식 권장 대응
503 UNAVAILABLE서비스가 일시적으로 과부하이거나 내려감기다렸다가 지수 백오프로 재시도
429 RESOURCE_EXHAUSTED분당·하루 한도를 넘김 (내 쪽 문제)분당이면 백오프 재시도, 하루 한도면 리셋까지 대기
500 INTERNAL서버의 예기치 못한 오류재시도, 계속되면 지원 문의
504 DEADLINE_EXCEEDED요청이 기한 안에 안 끝남클라이언트 기한 설정을 빼거나 늘림

핵심은 503은 기다리면 풀리는 에러라는 점입니다. 키를 새로 만들거나 요청 내용을 고칠 일이 아닙니다. 반대로 한도 초과인 429는 원인을 먼저 봐야 하는데, 그 구분은 gemini api 429 에러 글에 따로 정리했습니다. 400·402·403 같은 클라이언트 에러는 공식 문서도 재시도하지 말라고 합니다. 고쳐지지 않는 에러라 기다려 봐야 똑같이 실패합니다.

2. 파이썬 SDK는 503을 기본으로 재시도하지 않는다

공식 문제 해결 문서는 파이썬 SDK가 429·5xx를 기본으로 자동 재시도한다고 적고 있습니다. 하지만 google-genai 2.33.0에서 아무 옵션 없이 클라이언트를 만들고 503만 돌려주는 가짜 서버에 붙여 보면, 요청은 딱 1번 나가고 바로 예외가 올라옵니다.

from google import genai
from google.genai import errors

client = genai.Client()  # GEMINI_API_KEY 환경 변수를 읽는다

try:
    response = client.models.generate_content(
        model="gemini-3.8-flash",
        contents="503 에러가 뭔지 한 줄로 설명해 줘.",
    )
    print(response.text)
except errors.ServerError as e:
    print(type(e).__name__, e.code, e.status)
    print(e.message)

출력입니다(메시지는 가짜 서버가 보낸 값이고, 이때 서버에 들어온 요청은 1번이었습니다).

ServerError 503 UNAVAILABLE
The model is overloaded. Please try again later.

SDK 소스를 보면 이유가 보입니다. 재시도 설정(retry_options)이 비어 있으면 "1번 시도하고 멈춤"으로 처리합니다. 그러니 503이 나는 시간대에는 요청이 그냥 실패로 끝납니다.

예외 클래스 정리
5xx는 errors.ServerError, 4xx는 errors.ClientError이고 둘 다 errors.APIError를 상속합니다. 숫자는 e.code, UNAVAILABLE 같은 상태 이름은 e.status, 메시지는 e.message로 읽습니다.

3. HttpRetryOptions로 503 재시도 켜기

클라이언트를 만들 때 HttpOptions에 retry_options=types.HttpRetryOptions()를 넣으면 재시도가 켜집니다. 재시도할 때마다 SDK가 INFO 로그를 남기니, 처음에는 로그를 켜 두고 확인하는 게 좋습니다.

import logging
from google import genai
from google.genai import types

logging.basicConfig(level=logging.INFO, format="%(message)s")  # 재시도 로그 보기

client = genai.Client(
    http_options=types.HttpOptions(
        retry_options=types.HttpRetryOptions(),  # 기본값으로 재시도 켜기
    )
)

response = client.models.generate_content(
    model="gemini-3.8-flash",
    contents="503 에러가 뭔지 한 줄로 설명해 줘.",
)
print(response.text)

가짜 서버가 503을 두 번 보낸 뒤 정상 응답을 주게 해서 돌린 출력에서 재시도 줄만 추렸습니다. 1.6초, 2.7초를 쉬고 세 번째 요청에서 답을 받았습니다.

Retrying google.genai._api_client.BaseApiClient._request_once in 1.63 seconds as it raised ServerError: 503 UNAVAILABLE. ...
Retrying google.genai._api_client.BaseApiClient._request_once in 2.68 seconds as it raised ServerError: 503 UNAVAILABLE. ...
서버가 잠시 과부하라 요청을 못 받는다는 뜻입니다.

HttpRetryOptions 기본값

아무 값도 안 주면 아래 기본값이 쓰입니다(2.33.0 소스의 상수). 503이 계속 오면 요청 5번, 대기 약 1.7·2.7·4.5·8.5초를 거쳐 약 17초 뒤에 ServerError가 올라왔습니다.

필드 기본값 뜻
attempts5첫 요청을 포함한 총 시도 횟수 (0·1이면 재시도 없음)
initial_delay1.0초첫 대기 시간
exp_base2대기 시간을 몇 배씩 늘릴지
max_delay60초한 번 기다리는 시간의 상한
jitter1대기 시간에 섞는 무작위 값의 크기
http_status_codes408, 429, 500, 502, 503, 504재시도할 HTTP 상태 코드

상태 코드 말고도 연결 실패(ConnectError)와 타임아웃(TimeoutException)도 재시도 대상입니다. 400은 재시도를 켜 둬도 요청 1번에 바로 ClientError로 끝나는 것까지 확인했습니다.

429는 빼고 5xx만 재시도하기

기본값은 429도 재시도합니다. 분당 한도라면 괜찮지만, 하루 한도에 걸린 429는 몇 번을 다시 보내도 리셋 전까지 그대로라 시간만 버립니다. 429를 따로 처리하고 싶으면 http_status_codes에 재시도할 코드만 적습니다.

from google import genai
from google.genai import types

retry = types.HttpRetryOptions(
    attempts=4,          # 첫 요청 포함 4번
    initial_delay=2.0,   # 첫 대기 약 2초
    max_delay=30.0,      # 한 번 기다리는 시간의 상한
    http_status_codes=[500, 502, 503, 504],  # 429는 빼고 5xx만
)

client = genai.Client(http_options=types.HttpOptions(retry_options=retry))

이렇게 두면 429는 요청 1번에 ClientError로 올라오고, 503은 설정대로 재시도됩니다.

요청 하나에만 재시도 걸기

클라이언트 전체가 아니라 특정 요청에만 재시도를 걸고 싶으면 config의 http_options에 넣습니다. 클라이언트에 재시도가 꺼져 있어도 그 요청만 재시도됐습니다.

from google import genai
from google.genai import types

client = genai.Client()  # 클라이언트에는 재시도를 안 켠 상태

response = client.models.generate_content(
    model="gemini-3.8-flash",
    contents="503 에러가 뭔지 한 줄로 설명해 줘.",
    config=types.GenerateContentConfig(
        http_options=types.HttpOptions(
            retry_options=types.HttpRetryOptions(attempts=3),
        ),
    ),
)
print(response.text)

4. gemini 503이 계속될 때 — 다른 모델로 넘기기

재시도를 다 써도 503이면 같은 모델을 계속 두드리기보다 다른 모델로 넘기는 방법이 있습니다. 모델 목록을 앞에서부터 시도하고, 503일 때만 다음 모델로 갑니다.

from google import genai
from google.genai import errors, types

client = genai.Client(
    http_options=types.HttpOptions(
        retry_options=types.HttpRetryOptions(attempts=3),
    )
)

MODELS = ["gemini-3.8-flash", "gemini-3.5-flash-lite"]  # 앞에서부터 시도


def generate(prompt):
    last_error = None
    for model in MODELS:
        try:
            response = client.models.generate_content(model=model, contents=prompt)
            print("응답한 모델:", model)
            return response
        except errors.ServerError as e:
            if e.code != 503:
                raise  # 503이 아닌 서버 에러는 그대로 올린다
            print(model, "-> 503, 다음 모델로")
            last_error = e
    raise last_error


print(generate("503 에러가 뭔지 한 줄로 설명해 줘.").text)

첫 모델만 503을 내는 가짜 서버로 돌린 출력입니다. 첫 모델에 3번(재시도 포함), 두 번째 모델에 1번, 모두 4번 요청이 나갔습니다.

gemini-3.8-flash -> 503, 다음 모델로
응답한 모델: gemini-3.5-flash-lite
서버가 잠시 과부하라 요청을 못 받는다는 뜻입니다.
  • 재시도 횟수는 모델마다 따로 적용됩니다. 모델 수 × attempts만큼 요청이 나갈 수 있으니 attempts를 크게 잡지 마세요.
  • 대체 모델은 성능과 단가가 다릅니다. 모델별 요금은 gemini api 가격 글에서 비교해 보고 고르세요.

5. 504 DEADLINE_EXCEEDED와 타임아웃 설정

공식 에러 표는 504에 대해 "클라이언트 기한 설정을 빼거나 늘려 서버 기본값을 쓰라"고 합니다. 2.33.0 기본 클라이언트는 요청에 타임아웃이 아예 없습니다(가짜 서버에 들어온 요청의 timeout 값이 전부 비어 있었습니다). 반대로 내가 직접 넣을 때는 단위가 밀리초라는 점을 조심하세요.

from google import genai
from google.genai import types

client = genai.Client(
    http_options=types.HttpOptions(
        timeout=120_000,  # 밀리초 단위 = 120초
        retry_options=types.HttpRetryOptions(attempts=3),
    )
)

timeout=120이라고 쓰면 120초가 아니라 0.12초입니다. 이 값으로 만든 요청은 연결·읽기·쓰기 모두 120.0초로 나갔습니다.

타임아웃은 APIError로 안 잡힌다
타임아웃이 나면 SDK는 errors.APIError로 감싸지 않고 httpx.ReadTimeout을 그대로 올립니다. except errors.APIError만 걸어 두면 이 예외는 빠져나갑니다. 타임아웃까지 잡으려면 httpx.TimeoutException도 같이 받으세요(재시도를 켰다면 SDK가 먼저 재시도합니다).

자주 묻는 질문 (FAQ)

Q. 스트리밍 요청도 재시도되나요?
반만 됩니다. generate_content_stream()에서 첫 응답이 503이면 같은 retry_options대로 재시도돼 정상으로 이어졌습니다. 하지만 글자를 받던 중간에 503이 오면 재시도 없이 반복문 안에서 ServerError가 올라옵니다. 받아 둔 글을 지키는 방법은 gemini api streaming 글에 있습니다.

Q. async 클라이언트도 같은 설정을 쓰나요?
네. 같은 HttpOptions로 만든 client.aio.models.generate_content()도 503 두 번 뒤 세 번째 요청에서 성공했습니다. 따로 설정할 것은 없습니다.

Q. SDK 없이 REST로 직접 부르면요?
재시도는 직접 짜야 합니다. 공식 권장은 1초로 시작해 2·4·8초로 늘리고, 무작위 지연을 섞고, 최대 횟수를 두는 것입니다. 이 순서대로 429와 503만 골라 재시도하는 함수를 짠 예제가 gemini api 429 에러 글에 있습니다. 호출 부분만 바꾸면 REST 요청에도 같은 틀을 쓸 수 있습니다.

Q. 503이 몇 시간씩 계속되면요?
구글 개발자 포럼에는 503이 오래 이어졌다는 글이 여럿 있지만 원인을 공식으로 밝힌 답은 찾지 못했습니다. 재시도와 대체 모델로 버티면서, 발생 시각과 모델 이름을 적어 Google AI Studio나 포럼으로 알리는 것 말고는 공식으로 확인된 해결책이 없습니다.

마무리

정리하면 gemini api 503은 서버 쪽 일시 과부하라 기다렸다 재시도하면 되는 에러입니다. 다만 google-genai 2.33.0은 기본으로 재시도하지 않으니 HttpOptions(retry_options=types.HttpRetryOptions())를 꼭 넣으세요. 하루 한도 429까지 기다리기 싫으면 http_status_codes로 5xx만 고르고, 계속 503이면 대체 모델로 넘깁니다. 타임아웃은 밀리초 단위이고 APIError로 잡히지 않는다는 점도 같이 기억해 두세요.


📚 참고 출처 (2026년 10월 23일 확인 · google-genai 파이썬 SDK 2.33.0)
· Troubleshooting guide — Gemini API
· API errors — Gemini API
· googleapis/python-genai — GitHub

반응형

COMMENTS