PaddlePaddle/PaddleOCR · error · RequestTimeoutError
Request timed out after ${timeoutMs}ms
Error message
Request timed out after ${timeoutMs}ms What it means
RequestTimeoutError is thrown by the low-level fetch() when the underlying fetch rejects because the per-request timeout controller aborted — the request did not complete within effectiveTimeout milliseconds. The configured timeout is exposed on `timeoutMs` and the original network error on `cause`. It fires only when the user-supplied AbortSignal did not abort first (that case rethrows the user's abort reason instead).
Source
Thrown at api_sdk/typescript/src/internal/http.ts:218
const abort = () => abortController.abort();
timeoutController.signal.addEventListener("abort", abort, { once: true });
if (signal?.aborted) {
abort();
} else {
signal?.addEventListener("abort", abort, { once: true });
}
try {
resp = await this.fetchImpl(url, {
...init,
headers,
signal: abortController.signal,
});
} catch (e: unknown) {
if (signal?.aborted) {
throw userAbortReason(signal);
}
if (timeoutController.signal.aborted) {
throw new RequestTimeoutError(effectiveTimeout, { cause: e });
}
const message = e instanceof Error ? e.message : String(e);
throw new NetworkError(`Connection failed: ${message}`);
} finally {
clearTimeout(timeoutID);
signal?.removeEventListener("abort", abort);
}
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) {View on GitHub (pinned to 2661c7c0ef)
Solutions
- Pass a larger timeout: submitFile(model, path, payload, { timeoutMs: 300_000 }) or raise the SDK default
- Reduce payload size (downscale images, trim page ranges) so the upload fits the existing budget
- Retry transient slow requests — the class is designed to be retryable with backoff
- Check network path (proxy, VPN, DNS) if every request times out, not just large ones
Example fix
// before
const jobId = await client.submitFile(model, bigPdf, {});
// after
const jobId = await client.submitFile(model, bigPdf, {}, { timeoutMs: 5 * 60_000 });
// or for polling:
const result = await poller.waitForResult(jobId, { maxWaitTime: 10 * 60_000 }); Defensive patterns
Strategy: retry
Validate before calling
function sizeNeedsBiggerTimeout(bytes: number, bandwidthBps: number, timeoutMs: number): boolean {
return (bytes * 8) / (bandwidthBps) * 1000 > timeoutMs * 0.8;
} Type guard
function isRequestTimeout(e: unknown): e is RequestTimeoutError {
return e instanceof RequestTimeoutError;
} Try / catch
try {
await client.submitFile(model, filePath, payload, { timeoutMs: 300_000 });
} catch (e) {
if (e instanceof RequestTimeoutError) {
if (e.timeoutMs >= 300_000) throw new Error("Upload too slow — reduce file size");
return client.submitFile(model, filePath, payload, { timeoutMs: e.timeoutMs * 2 });
}
throw e;
} Prevention
- Scale timeoutMs with payload size (rough rule: at least bytes/bandwidth plus slack)
- Pass generous timeouts for uploads and result downloads; keep tight ones only for cheap status calls
- Retry on RequestTimeoutError with doubled budget before assuming failure
When it happens
Trigger: Any HTTP call where the server or network is slower than the effective timeout: uploading a very large file to submitFile on a slow link, polling a status endpoint behind a slow proxy, or a default timeout that is too small for big payloads. The poller passes its remaining wait budget as timeoutMs, so long-poll loops near their deadline also hit this.
Common situations: Default request timeout too low for 50+ MB PDF uploads; high-latency regions far from the API endpoint; mobile/flaky networks; cold-start backends that take seconds to respond; containers with constrained bandwidth.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- OCR result item is missing result.ocrResults.
- Document parsing result item is missing result.layoutParsing
- Job ${job.jobId} is a ${job.task} job, not a ${expectedTask}
- Expected a JSON response body.
- PaddleOCR official API request failed.
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/a3bf27fe9cb21d73.
Report an issue: GitHub.