The File Upload
Moving a file from someone's machine into yours, with the failures handled up front.
The problem it solves
Uploads fail in more ways than any other input: wrong type, too large, slow connection, dropped mid-transfer. Most implementations discover each failure only after the user has waited.
The rule that fixes most upload experiences is to validate before transferring. File type, size, and count are all knowable in the browser the instant a file is chosen. Rejecting a 300 megabyte file after a four-minute upload is a choice, and it is the wrong one.
- 1State the accepted types and the size cap next to the control, before anything is selected.
- 2Accept both click-to-browse and drag-and-drop, and give the drop zone a visible hover state so it is obvious it is a target.
- 3Validate type, size, and count locally the moment a file is picked, and reject with a specific reason.
- 4Show per-file progress with a real percentage, plus a cancel control for each one.
- 5On failure, keep the file in the queue and offer Retry rather than making the person find it again.
- 6Show a thumbnail or filename confirmation once it lands, so success is visible rather than assumed.
For large files, chunked uploads with resume turn a flaky connection from a total loss into a pause. This matters most on mobile, where the tab may be backgrounded and the network may switch networks mid-transfer.
Upload copy that leaves people stuck
- Upload failed
- File too large
- Invalid file type
- Drop files here
- Processing...
Upload copy that resolves it
- report.pdf did not finish uploading. The connection dropped at 62 percent. Retry
- holiday.mov is 240 MB. The limit is 100 MB. Try a shorter clip or compress it first
- notes.pages cannot be read here. Accepted: PDF, DOCX, TXT. Export as PDF and try again
- Drag files here, or browse. PDF, PNG or JPG, up to 25 MB each
- Scanning invoice.pdf for viruses. About 10 seconds
Security belongs in the design, not only in the backend. Never trust the client-side type check, generate your own filenames rather than using the uploaded one, and be explicit about whether an uploaded file becomes publicly reachable by URL. Users routinely assume a private upload is private, and are right to be angry when it is not.
Worked example
A hypothetical size ceiling
A tool caps uploads at 25 megabytes and says so only in an error. Support sees repeated tickets from people photographing documents on modern phones, where a single scan can exceed the cap. Two fixes compete: raise the cap, or downscale images in the browser before upload. The second costs less to run and removes the error for the common case, which is usually the better trade.
When it fits
- The product genuinely needs the user's own files rather than a link or a paste.
- Accepted types and size limits are stable enough to state up front.
- You can show per-file progress and support cancel and retry.
- Storage and scanning costs are understood, since uploads are the easiest surface to abuse.
When it backfires
- Validation happens server-side only, so rejections arrive after the wait.
- A failed upload clears the queue, forcing the person to reselect every file.
- Progress is a spinner rather than a percentage, so a slow upload is indistinguishable from a dead one.
- Privacy is ambiguous, and an upload the user thought was private is served from a guessable public URL.
Products using it
Dropbox
Uploads in chunks with resumable transfers, so an interrupted connection does not restart the file.
Google Drive
Shows a per-file progress panel with individual cancel controls, and keeps failed items listed for retry.
Gmail
Blocks disallowed attachment types at selection time and states the reason rather than failing on send.
The psychology under it
The takeaway
Validate before the transfer, show real progress per file, and keep failed files in the queue for retry.
Finished the teardown? Bank it and the day counts toward your run.
