PaddlePaddle/PaddleOCR · warning · ServiceUnavailableError
Service unavailable: ${text}
Error message
Service unavailable: ${text} What it means
ServiceUnavailableError (extends APIError, statusCode 503 or 504) is thrown when the API or an upstream gateway answers 503 (overloaded/maintenance) or 504 (gateway timeout). The server's explanation text is embedded in the message. These are transient server-side conditions; the request itself was valid.
Source
Thrown at api_sdk/typescript/src/internal/http.ts:243
}
if (resp.ok) return resp;
let text = await resp.text();
try {
const payload = JSON.parse(text) as { msg?: string; message?: string; errorMsg?: string };
text = payload.msg || payload.message || payload.errorMsg || text;
} catch {
// Keep raw response text.
}
if (resp.status === 401 || resp.status === 403) {
throw new AuthError(`Authentication failed: ${text}`);
} else if (resp.status === 400) {
throw new InvalidRequestError(`Bad request: ${text}`);
} else if (resp.status === 429) {
throw new RateLimitError(`Rate limit exceeded: ${text}`);
} else if (resp.status === 503 || resp.status === 504) {
throw new ServiceUnavailableError(resp.status, `Service unavailable: ${text}`);
} else {
throw new APIError(resp.status, text);
}
}
}
function requireJobId(data: SubmitResponse): string {
if (!data || typeof data.jobId !== "string" || data.jobId.length === 0) {
throw new ResponseFormatError("Submit response is missing jobId.");
}
return data.jobId;
}
View on GitHub (pinned to 2661c7c0ef)
Solutions
- Retry with exponential backoff and jitter — 503/504 usually clear on their own within seconds to minutes
- Reduce batch size or submission concurrency to lower backend pressure
- Check the service status page / announcement channels for ongoing incidents
- Circuit-break: if >50% of retries still fail, pause the pipeline for a cooldown instead of hammering the API
Example fix
async function resilientSubmit(fn: () => Promise<T>, tries = 5): Promise<T> {
for (let i = 0; ; i++) {
try { return await fn(); }
catch (e) {
if (e instanceof ServiceUnavailableError && i < tries - 1) {
await sleep(2 ** i * 1000 + Math.random() * 500);
continue;
}
throw e;
}
}
} Defensive patterns
Strategy: retry
Type guard
function isServiceUnavailable(e: unknown): e is ServiceUnavailableError {
return e instanceof ServiceUnavailableError;
} Try / catch
try {
await client.submitJson(model, payload);
} catch (e) {
if (e instanceof ServiceUnavailableError) {
await backoff(3, () => client.submitJson(model, payload));
} else {
throw e;
}
} Prevention
- Wrap all API calls in exponential-backoff-with-jitter retries for 503/504
- Add a circuit breaker so sustained outages pause the pipeline instead of amplifying load
- Check service status feeds during scheduled maintenance windows before deploying batch jobs
When it happens
Trigger: Any HTTP call during backend overload, rolling maintenance windows, or when an upstream service behind the API gateway exceeds its own timeout (504). Typically appears across many requests at once rather than isolated to one call.
Common situations: Peak-hour capacity crunches; regional outages; deployment windows; large batch workloads stressing the service; gateway timeouts on unusually heavy documents.
Understand the failure class
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Related errors
- Rate limit exceeded: ${text}
- Expected a JSON response body.
- PaddleOCR official API request failed.
- Response body is missing data.
- Request timed out after ${timeoutMs}ms
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/c02600ad74a46478.
Report an issue: GitHub.