Fix 503 “no available accounts” on an OpenAI-compatible API.

A 503 with the message “no available accounts” means the relay reached the gateway, but the upstream account pool had no account whose status, model allowlist and rate budget could accept the request. It is distinct from 401, 429 and 504 — and the recovery path is different.

503 Service Unavailableno available accountsaccount_select_failedupstream account pool

What the error actually means

The relay returned HTTP 503 with a structured JSON body. The exact phrase no available accounts appears in the error field of the upstream log entry openai_chat_completions.account_select_failed. RFC 9110 §15.6.4 documents 503 for cases where the server cannot currently handle the request — including account-pool exhaustion behind a reverse proxy.

Failure happens at the pool-selection step, before any upstream provider is even contacted. /v1/models still returns 200 because that route never needs a chosen upstream account. /v1/chat/completions returns 503 because every candidate account failed its preflight.

What the relay logs look like

Two clean log lines captured from journalctl -u sub2api on monkeytheme.com at 2026-08-08T13:25–13:26+08:00, against /v1/chat/completions for the model gpt-5.6-sol:

{"service":"sub2api","env":"production","component":"http","request_id":"05217724-bffa-43c7-9904-8ee9a3545057","path":"/v1/chat/completions","method":"POST","component":"handler.openai_gateway.chat_completions","user_id":1,"api_key_id":53,"group_id":9,"model":"gpt-5.6-sol","stream":true,"error":"no available accounts","excluded_account_count":1}
{"service":"sub2api","env":"production","component":"http","request_id":"607353af-0bd0-4a7e-aecd-558db4daf4de","path":"/v1/chat/completions","method":"POST","component":"handler.openai_gateway.chat_completions","user_id":1,"api_key_id":53,"group_id":9,"model":"gpt-5.6-sol","stream":true,"error":"no available accounts","excluded_account_count":0}

The excluded_account_count field is the strongest signal:

Count valueWhat it tells you
0No account was even attempted — the pool was empty before selection ran.
1 or higherFailover ran and tried every account; every one was excluded (rate, status, model allowlist).

When excluded_account_count is 0, the operator knows to look at pool health, not at any one account. When it is ≥ 1, the operator knows to look at the per-account exclusion reason logged just before this entry.

How this differs from 401 / 429 / 504

Failure modeWhere it happensWhat the client should do first
401 invalid tokenAuthenticationFix Authorization: Bearer header
404 model not foundRouting / model listPull /v1/models and copy the exact ID
429 rate limitA healthy upstream accountHonor Retry-After, drop concurrency, add bounded backoff
504 gateway timeoutUpstream did not respond in timeRetry once, capture request_id, escalate if persistent
503 no available accountsPool selection (before upstream)Wait briefly, drop concurrency, switch model if persistent

Do not collapse these into one “API error”. Each one points to a different layer, and the fix is different.

Capture one complete, redacted failure

curl -sS -D /tmp/headers.txt -o /tmp/body.json \
  https://monkeytheme.com/v1/chat/completions \
  -H "Authorization: Bearer ***" \
  -H "Content-Type: application/json" \
  -d '{"model":"MODEL_ID_FROM_YOUR_LIST","messages":[{"role":"user","content":"Reply with OK"}],"max_completion_tokens":16}'

sed -n '1,20p' /tmp/headers.txt
python3 -m json.tool /tmp/body.json

Record the HTTP status, the JSON error string, the request_id header (if present), the timestamp, the endpoint and a redacted request shape. Never paste the Bearer token into a ticket or screenshot. If the relay responds 503, the operator can match your request_id to the matching account_select_failed log entry and see whether failover ran.

This review did not deliberately trigger no available accounts against a customer key. The log lines above are redacted operator-side entries captured during a normal traffic window, not synthetic probes. If you see this on your own key, your own real request_id is the strongest evidence to send support.

Recovery checklist for the caller

  1. Confirm the Base URL is https://monkeytheme.com/v1 and the key starts with sk-.
  2. Pull /v1/models with the same key. A 200 here rules out 401 and routing.
  3. Drop concurrency by at least half and wait 10–15 seconds before the next probe.
  4. Send one small request with stream: false so you get a single 503 response and a clean request_id.
  5. If the same request_id still returns 503 after 60 seconds, switch to a model that you know has a healthy pool (compare against /v1/models).
  6. If the error is model-specific and persistent, send support the timestamp, the model name, the redacted body and the request_id.

How the official SDKs interact with this

The OpenAI Python and Node.js SDKs currently retry eligible 429 and connection errors twice by default. They do not currently retry 503 from no available accounts, because 503 is the gateway saying “try a different upstream or wait”, not the SDK saying “this is a transient transport error”. A tight application-level retry loop will multiply traffic against an already-empty pool. Set max_retries=0 temporarily while you capture one clean failure, then restore an intentional retry policy.

What this page does not claim

A successful /v1/models does not prove generation capacity for any specific model. A single 503 from no available accounts is not a sign that the relay is down — the relay is up, the upstream account pool is exhausted. A persistent 503 across many models at the same time, with the same excluded_account_count: 0, does indicate pool-level capacity that an operator needs to investigate.

Sources

FAQ

What does “no available accounts” mean on an OpenAI-compatible API?

It means the relay picked a key and route, but the upstream account pool had no account whose status, model allowlist and rate-limit budget could accept the request. The request reached the gateway, not your key or your prompt.

Is this a 503 or a 401?

MonkeyAI returns 503 with a structured JSON body. RFC 9110 §15.6.4 documents 503 as the right code when the server is temporarily unable to handle the request, regardless of upstream cause. The body identifies the failure mode, not the HTTP status alone.

Does it look like a 429 or a 504?

No. 429 means a specific request or token pacing limit on an otherwise healthy account. 504 means the upstream did not respond in time. “no available accounts” means no account can take the request at all — the failure is at the pool-selection layer, before the upstream is even contacted.

Why does /v1/models still work?

Model-list and key-info routes do not require a chosen upstream account. They confirm the key, the Base URL and the route work. They do not prove that an inference account is currently able to serve your model.

Should I retry immediately?

Not in a tight loop. Pool exhaustion is usually temporary, but a fast retry just adds pressure. Wait a few seconds, drop concurrency, then send one probe. If the error persists for a minute or more, switch models or contact the operator with the request_id.

Can I confirm it on the server side?

Yes — the relay emits openai_chat_completions.account_select_failed with the JSON error field set to “no available accounts”. The accompanying excluded_account_count is the strongest signal: 0 means no account was even attempted; ≥1 means failover tried every account and every one was excluded.

Is the failure on my client or on the gateway?

The failure is on the gateway’s account pool. Your key, header and Base URL are fine — /v1/models returns 200, /v1/chat/completions returns 503. Treat it as a temporary capacity issue, not a configuration bug.

Related guides

API 504 timeout troubleshooting

Separate 504 from 503, capture request_id and time, then retry once.

Open guide

ChatGPT Plus 5-hour OAuth pool exhaustion

The specific root cause behind most 503s on the OpenAI ChatGPT Plus OAuth pool — read upstream 401s and the rolling 5-hour window before retrying.

Open page

HTTP 429 rate limit troubleshooting

Separate rate-limit 429 from credit errors and honor Retry-After.

Open guide

API 401 invalid token

Confirm the header format and that the key belongs to monkeytheme.com.

Open guide

Model not found

Pull /v1/models with the same key, copy the exact ID.

Open guide

AI API gateway for developers

6-step setup, pre-flight checklist and 401/404 probes for SDKs and coding agents.

Open guide

Contact support

Send a redacted request_id, model and timestamp.

Open page