Troubleshooting: FILE_SCAN_QUARANTINED
A download attempts fails with a402 and error.code equal to
FILE_SCAN_QUARANTINED:
scan_id and a scan_eta_seconds estimate precisely so you can poll to a
verdict instead of guessing.
What the scan state machine does
Every uploaded file moves through three states:pending— the upload landed and the scanner has not reached a verdict yet. A download or attachment fetch on apendingfile returnsFILE_SCAN_QUARANTINEDwhile the scan completes.clean— the scanner returned no threat. Downloads succeed from here on.quarantined— the scanner flagged the content. The file is dropped before it can reach a delivery, an attachment fetch, or an AI agent, exactly like an inbound-email attachment the threat scan flags malicious: the quarantine is a fault-line decision, not a suppression rule.
Check scan_status before deciding
Look up the file row withGET /api/v1/files/{id}
and read the row’s scan fields. A pending row is a wait case; a
quarantined row is a replace case. The details.scan_id in the 402 envelope
identifies the individual scan run — keep it when you escalate a verdict, so
support can read the same scanner verdict you got rather than re-guessing
from the file bytes.
Retry semantics: poll to clean, never replay the artifact
Poll-safe and replay-unsafe live in one loop, so branch on the state:
The contrast with a DLQ retry matters: a dead-letter entry is a delivery
artifact you replay after fixing its fault. A quarantined file is never
replayed — the scanner verdict attaches to the content itself. If you
blind-retry a quarantined artifact on every poll tick you also burn the
rate-limit budget on deterministic 402s; bound the loop to the ETA the
envelope gives you.
Tenant-owned first controls
A true-positive verdict starts at your own intake rules, which you control per tenant:- Allowed content types — uploads outside your allow-list fail pre-flight before they ever enter the scanner. Tighten the list to the types your flows genuinely accept.
- Size ceilings — a file above your upload cap is rejected at intake; the scanner never sees it.
- Uploader allowlists and endpoint hygiene — quarantines cluster on the uploaders and endpoints that accept arbitrary binaries from the outside. Restrict who can push content and the verdict rate falls with it.
quarantined verdict
is the scanner doing its job, and the fix belongs in the intake rule, not in
an escalation.
Escalate a wrong verdict
When a benign, business-critical file is held — and the intake rules above check out — open a support ticket with three things: the file ID, thescan_id from the 402 envelope, and a short note on why the content type is
expected in your flow. Support reads the same scanner verdict and either
confirms the hold or restores the file on the platform side. Re-uploading the
identical bytes without this step re-enters the same verdict, so escalate
first when the content matters.
See also
- Files API — the list/get endpoints that carry the scan fields, plus upload and download.
- Troubleshooting: fan-out and upload errors
— the sibling intake-rejection codes (
INVALID_FILE_TYPE,MAGIC_BYTE_MISMATCH,FILE_TOO_LARGE) that fail before the scanner runs. - Glossary: Quarantine — how a fault-driven hold differs from a permanent DLQ exhaust lane.