PaddlePaddle/PaddleOCR · warning · InvalidRequestError
Unsafe resource filename: ${key}
Error message
Unsafe resource filename: ${key} What it means
Raised as NetworkError from fetch_jsonl in paddleocr/_api_client/_http.py:192 when the connection to the pre-signed resultUrl fails (DNS, TLS, reset, refused). The result file lives on object storage, a different host from the API — so this can fail even when API connectivity is fine (e.g. storage domain blocked). The job succeeded; only the artifact download failed and can be retried while the pre-signed URL is valid.
Source
Thrown at api_sdk/typescript/src/client.ts:374
for (const [key, val] of Object.entries(value)) {
if (typeof val === "string") {
result[key] = val;
}
}
return result;
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null;
}
function isDocParsingResult(result: OCRResult | DocParsingResult): result is DocParsingResult {
return result.pages.some((page) => "markdownText" in page);
}
function safeMapKeyFilename(key: string): string {
if (!key || key === "." || key === ".." || key.includes("/") || key.includes("\\") || key.startsWith(".")) {
throw new InvalidRequestError(`Unsafe resource filename: ${key}`);
}
return key;
}
function safeUrlBasename(url: URL): string {
const name = basename(url.pathname) || "resource";
if (name === "." || name === "..") {
return "resource";
}
return name;
}
function resourceExtension(resourceUrl: string): string {
try {
const url = new URL(resourceUrl);
return extname(url.pathname);
} catch {
return "";View on GitHub (pinned to 2661c7c0ef)
Solutions
- Extract jsonUrl from job status and test it directly (curl) from the same environment
- Whitelist the object-storage/CDN host in firewall/proxy rules
- Retry promptly — pre-signed URLs expire; if expired, re-fetch job status for a fresh URL
- Check the storage provider's status page for outages
Example fix
# verify the result URL is reachable status = client.get_job_status(job_id) url = status["resultUrl"]["jsonUrl"] import requests r = requests.get(url, timeout=30) print(r.status_code, len(r.content))
Defensive patterns
Strategy: retry
Validate before calling
# preflight: is the result storage host reachable?
status = client.get_job_status(job_id)
url = status.get("resultUrl", {}).get("jsonUrl")
if url:
host = urlparse(url).hostname
try:
socket.getaddrinfo(host, 443)
except socket.gaierror:
print(f"Result storage host {host} not resolvable — check firewall/DNS") Try / catch
from paddleocr._api_client.errors import NetworkError
try:
results = client.get_result(job_id)
except NetworkError:
time.sleep(3)
results = client.get_result(job_id) # pre-signed URL still valid; retry download Prevention
- Whitelist the object-storage/CDN host in firewalls, not just the API domain
- Retry downloads promptly — pre-signed URLs expire
- Extract and curl the jsonUrl when diagnosing environment-specific blocks
When it happens
Trigger: client.get_result() where the object-storage host of resultUrl.jsonUrl is unreachable: firewall blocks the storage domain, DNS fails for the CDN bucket, or TLS interception breaks the storage cert.
Common situations: Corporate firewalls whitelisting the API domain but not object storage/CDN domains; egress-restricted containers; regional storage outages; expired pre-signed URLs surfacing as connection-level errors via middleboxes.
Related errors
- Either fileUrl or filePath is required.
- OCR result page is missing prunedResult.
- Document parsing result page is missing markdown.text.
- Model ${model} is not an OCR model.
- Connection failed: {e}
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/30e6854e174b7f23.
Report an issue: GitHub.