All posts
Product design

Error Messages and Error States: UX Patterns That Help Users Recover

Error state UX, copy first: a three-part error message formula, plain-language rewrites of common errors, and recovery actions that get users moving again.

By Mehdi Hassan7 min read

The short answer

Good error state UX tells users what happened, why it happened, and what to do next, in plain language next to the problem. Each message should offer a recovery action (retry, fix the field, restore a draft) and never blame the user or expose raw codes. Write the words first, then design the state.

Key takeaways

  • Use a three-part formula for every error: what happened, why, and what to do now.
  • Put the message where the problem is: on the field, the row or the action, not in a generic toast.
  • Every error needs a recovery action. A message without a next step is a dead end.
  • Never lose user input on an error. Preserving drafts is a design decision, not just an engineering one.
  • Keep an error copy inventory so the same failure always says the same thing.

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.

Frequently asked questions

Should error messages include error codes?
Show error codes only as secondary detail, never as the message itself. A small reference like "Error ID: 7F3A" under the plain-language message helps support find the log without confusing the user. Put it in a copyable format and keep it visually quiet, so people who don't need it can ignore it and people contacting support can paste it.
Is it OK to use humor in error messages?
Use humor sparingly and never when the user has lost money, time or data. A light line on a harmless 404 can work, but a joke on a failed payment or a lost draft reads as dismissive. The safer default is calm, direct language that takes responsibility when the problem is yours and gets the user to the fix quickly.
Should forms validate on every keystroke?
Usually not. Validating while someone is still typing flags errors before they've had a chance to finish, which feels like nagging. A common pattern is to validate a field when the user leaves it, then re-validate on each keystroke once it has shown an error, so the message clears the moment the input becomes valid.
How do you keep error messages consistent across a product?
Keep an error copy inventory: a shared document or design-system page listing each failure, its cause, its approved message and its recovery action. Engineers pull from it instead of writing messages in code, and designers review new entries. The same failure then always says the same thing, which builds trust and makes support far easier.
What tone should error messages use?
Use a calm, direct and specific tone. Say what happened in plain words, take responsibility when the system failed, and avoid blaming phrases like "you entered an invalid value." Apologize only when the problem is genuinely on your side, and once is enough. The tone should match the rest of your product, just with less personality.

· CEO & Design Director

Copywriter, designer and developer, and founder of Designify Studio. Over five years, 60+ projects across 14+ industries, for startups that have raised $300M+.

Want this done for you? Brand & design sprint, $3,000.

A brand refresh or redesign, plus design explorations for your website and product. $3,000, one-time, fixed price. Book a free 30-minute call to see if it fits.

Schedule Call