What makes good error state UX?
Good error state UX helps the user recover, not just know that something broke. Every error message has one job: get the person from "that didn't work" to "done" with the fewest possible steps. That's mostly a writing problem. The visual treatment matters, but a red box with a vague sentence is still a dead end.
Errors sit in the same family as empty and loading states, and we treat them together in our guide to web app UI design. The difference is emotional: an error interrupts someone who was trying to do something. That raises the stakes for tone, placement and what you offer next.
What is the three-part error message formula?
The three-part error formula is: what happened, why it happened, and what to do now. If you can only fit one part, keep the third. Users can act on "Re-enter your card number" even without the why.
Part | Question it answers | Example |
|---|---|---|
What happened | Did my action work? | Your payment didn't go through. |
Why | Was it me or the system? | Your bank declined the card. |
What to do now | How do I fix it? | Try another card or contact your bank. |
Put together: "Your payment didn't go through. Your bank declined the card. Try another card or contact your bank." Three short sentences, no jargon, and the user knows the problem isn't your product. When the cause is on your side, say so: "We couldn't save your changes because of a problem on our end. Your draft is safe. Try again in a moment."
How do you rewrite error messages in plain language?
Rewrite each error by removing system language, naming the thing the user was doing, and adding the next step. Most bad error messages are written by the code that threw them. Here are common rewrites we make when we review products.
Before | After |
|---|---|
Error 500: Internal Server Error | Something went wrong on our side, and your changes weren't saved. Try again, or contact support if it keeps happening. |
Invalid input | Enter a date in the format MM/DD/YYYY. |
Authentication failed | That email and password don't match. Try again or reset your password. |
Request timed out | This is taking longer than usual. Check your connection and retry. |
File upload failed | This file is over the 25 MB limit. Compress it or upload a smaller file. |
Permission denied | Only workspace admins can change billing. Ask an admin to make this change. |
Something went wrong | We couldn't load your reports. Your data is safe. Retry, or check our status page. |
Notice the pattern: each "after" names the object (changes, date, file, billing), keeps the user's data reassured where relevant, and ends with a verb. Avoid words like "invalid", "illegal" and "fatal", and never put an exclamation mark on an error.
Where should error messages appear?
Error messages should appear as close as possible to the thing that caused them. Placement tells the user what to fix before they read a word.
- Field errors sit directly under the field, connected to it for screen readers, and stay until the field is fixed.
- Form-level errors appear at the top of the form with a summary that links to each problem field, for long forms.
- Row or item errors mark the specific row in a table ("3 of 40 rows failed to import") with a way to see and fix them.
- Action errors (save, send, delete) appear on or near the button that triggered them, or as a persistent banner if the page state changed.
- Page or app errors replace the content area with an in-app error screen that keeps the navigation, so users aren't stranded.
Toasts are the most overused placement. A toast that disappears after a few seconds is fine for "Copied", but it's the wrong home for an error the user needs to act on. Forms are where most errors live, so pair this guide with our web form design best practices, which cover when to validate inline and when to wait for submit.
Which recovery actions should every error offer?
Every error should offer at least one recovery action that matches its cause. The right action depends on whether the user, the system or a third party is responsible.
Cause | Recovery action | Example label |
|---|---|---|
User input | Focus the field and explain the fix | Enter a valid email |
Temporary system issue | Retry, ideally automatic with a manual fallback | Retry now |
Lost connection | Queue the action and sync when back online | Saved offline, will sync |
Permissions | Name who can do it, offer to request access | Request access |
Third-party failure | Say which service failed and offer an alternative | Reconnect Google Drive |
Destructive action failed | Confirm nothing was lost and offer undo | Undo |
The rule underneath all of these: never lose the user's work. If a long form fails to submit, keep every value. If an upload fails halfway, resume rather than restart. Preserving input is often the difference between an error that annoys and one that makes people leave.
How to handle the in-app 404 and deleted-item screens
A 404 inside a logged-in app usually means a link to something that was deleted, moved or never shared with this user. Those are three different messages.
Deleted: "This project was deleted by Sam on March 4. Restore it from Trash or go back to Projects."
No access: "You don't have access to this project. Request access from the owner."
Not found: "We couldn't find that page. It may have moved. Search projects or go to your dashboard."
Keep the app navigation visible on all three so the user can carry on. A full-screen marketing-style 404 inside the product feels like being logged out.
How do error states differ from empty and loading states?
An error state means something failed; an empty state means nothing exists yet; a loading state means the answer is on its way. Mixing them up is a common bug that looks like a design problem. When a request fails and the UI shows "No projects yet", the user thinks their data is gone.
Design all three for every data-driven component, and make sure engineering maps each to the right condition. Our guides to empty state design and loading state design cover the other two. A useful habit is a single component spec with all three variants side by side, so nobody ships one without the others.
That last point is a core accessibility requirement, not a nice-to-have. Our accessible web app design checklist covers how to connect error text to fields and move focus after a failed submit.
How should AI and transaction errors be handled?
AI features and financial transactions need extra care because the failure is often ambiguous. An AI answer can be wrong without throwing an error, and a blockchain transaction can be pending, failed or dropped. Both need states that say clearly what is known and what isn't.
For AI, show uncertainty, let users edit or regenerate, and make it easy to report a bad answer; we go deeper in designing for AI errors and hallucinations. For payments and crypto, never show "failed" until you're sure, and always say whether money moved. Our guide to DeFi UX design covers pending, confirmed and reverted transaction states.
