Guide

Error State Design Patterns: How to Design for When Things Go Wrong

Error State Design Patterns: How to Design for When Things Go Wrong

It’s the silence after a click. You’ve just filled out a form, hit “Submit,” and now you wait. One second. Two. Nothing happens. No confirmation, no error, just a dead-end UI. This digital void is where user trust goes to die, yet it’s an experience we ship every day. We obsess over happy paths, crafting perfect onboarding flows and beautiful success screens. But what happens when the connection drops, the payment fails, or an API times out?

That’s where the real work of product design begins.

This is what I mean: great error state design patterns aren’t about apologizing for mistakes. They are about maintaining momentum. A user who encounters a well-handled error feels guided, not blocked. They understand what went wrong, what to do next, and trust that the system has their back. Poor error handling ux, on the other hand, creates frustration, abandonment, and support tickets. The difference between a loyal user and a lost one often lives in these moments of failure state design.

Last week, I watched a PM at a Series B company map out their team's last quarter. A huge chunk of it was spent chasing down bugs related to unhandled exceptions. They were the exact kinds of edge cases every PM misses, leading to costly post-launch fixes. This article is a catalog of proactive solutions. We will break down ten specific error message patterns, from inline validation to complex scenarios like network failures. For each pattern, you’ll get clear guidance on when to use it, what to say, and how it should look. This is your field guide to designing for when things go wrong, ensuring the silence after the click is never a dead end.

1. Inline Validation

There's a special kind of dread that comes with filling out a long form, hitting "Submit," and being told you made a mistake somewhere on the page. The most proactive pattern is to prevent the error before it happens. This is Inline Validation. It’s a preventative measure that checks user input as it’s being entered, providing instant, contextual guidance right where the user is working.

This pattern transforms form-filling from a guessing game into a guided conversation. The basic gist is this: instead of waiting for a submission to tell a user their password is too weak, the system tells them immediately. Think of Stripe's credit card forms that detect the card type and validate the number in real time. This approach, as noted in Jakob Nielsen's research on usability heuristics, dramatically reduces user frustration and improves data quality at the source.

  • When to use it: For any form where users enter structured data like emails, passwords, phone numbers, or credit card information.

  • Copy best practices: Be clear and constructive. Instead of "Invalid input," say "Password must be at least 8 characters long." Show the rule, and then confirm when it’s met.

  • Visual example: A red border and helper text appear below the input field upon detecting an error, turning green with a checkmark upon successful validation.

2. Toast Notifications

A toast is a non-modal, unobtrusive message that appears briefly to provide quick feedback. It’s perfect for low-priority errors or confirmations that don't need to interrupt the user's flow. Did the "Save" action fail because of a momentary network blip? A toast is often enough.

It’s called a "toast" because it pops up from the bottom of the screen, much like toast from a toaster.

  • When to use it: For low-severity, temporary errors, especially those related to background processes like auto-saving or syncing.

  • Copy best practices: Keep it short and simple. "Couldn't save changes. We'll try again." An optional "Retry" button can add value.

  • Visual example: A small, rounded banner slides up from the bottom of the screen, displays a message for 3-5 seconds, and then slides back down.

3. Full-Page Errors

Some errors are showstoppers. When a core piece of your application fails to load or an entire section is inaccessible, a small toast won't cut it. This is where a Full-Page Error pattern comes in. It takes over the entire viewport to clearly communicate a critical failure, explain what happened, and provide a clear path forward.

  • When to use it: For critical system failures, when the primary content of a page cannot be displayed or the user's action cannot be completed at all.

  • Copy best practices: Be honest and direct. "We couldn't load this dashboard." Provide a primary action like "Try Again" and a secondary escape hatch like "Go to Homepage" or "Contact Support."

  • Visual example: A centered layout with a headline, a brief explanation, and one or two prominent buttons. An illustration can soften the message.

4. Empty Error States

What happens when a search yields no results or a filtered list comes up blank? This isn't a system failure, but it can feel like one to the user. An Empty Error State transforms a blank screen into an opportunity for guidance. It acknowledges the lack of results and helps the user self-correct.

  • When to use it: For "no results found" in searches, empty dashboards after filtering, or when a user has no items in a list (e.g., "No projects created yet").

  • Copy best practices: Be encouraging. "No results for 'ux design patterns'." Suggest alternative actions: "Try searching for a broader term" or "Check your spelling."

  • Visual example: A friendly illustration with clear text explaining the state and offering actionable suggestions or links to create the first item.

5. Network Failure

Your application doesn't live in a vacuum. It depends on a network connection that can be slow, intermittent, or completely absent. The Network Failure pattern addresses this reality by communicating the connection issue clearly and, where possible, enabling offline functionality. It’s a key part of resilient error state ui design.

  • When to use it: When the application detects a lost or unstable internet connection.

  • Copy best practices: State the problem directly. "You are currently offline." If possible, explain what the user can still do: "You can continue writing, and we'll save your changes when you're back online."

  • Visual example: A persistent banner at the top of the screen (like in Google Docs) or a modal overlay for actions that require a connection. Figr's analysis of Zoom's network degradation states shows how to handle this gracefully.

6. Timeout Error

The user clicks a button, a spinner appears, and... it just keeps spinning. A Timeout Error occurs when the application is waiting for a response from a server, but it takes too long. A good pattern here is to stop waiting, inform the user, and give them control.

  • When to use it: When a server-side operation (like loading data or processing a request) exceeds a reasonable time limit, typically 10-15 seconds.

  • Copy best practices: Be specific. "The request is taking longer than expected." Offer options: "Cancel" or "Keep Waiting." This respects the user's time.

  • Visual example: The loading indicator is replaced by a message and action buttons. This could be inline or in a small modal.

7. Permission Denied

"You do not have access to view this page." This is a common but often frustrating error. The Permission Denied pattern aims to make this roadblock less of a dead end by explaining why access is restricted and what the user can do about it.

  • When to use it: When a user attempts to access a feature, page, or resource that their role or permissions do not allow.

  • Copy best practices: Explain the situation and provide a path forward. "This feature is only available for Admins." Then, offer a helpful action: "Request access from your workspace owner" or "Learn more about user roles."

  • Visual example: A full-page state or a modal explaining the restriction, often with a "Request Access" button that triggers a notification to an admin. Wise's handling of frozen card edge cases is a great reference.

8. The 404: Page Not Found

The 404 is the classic internet error. The user has followed a broken link or mistyped a URL. While unavoidable, a 404 page is a fantastic branding and user experience opportunity. The best 404 patterns help users reorient themselves instead of just showing them the door.

  • When to use it: When the server cannot find the requested URL.

  • Copy best practices: Be a little playful, but stay helpful. "Oops. We can't find that page." The most important elements are a prominent link to the homepage and a search bar to help the user find what they were looking for.

  • Visual example: GitHub’s parallaxing 404 page is iconic. The goal is a branded, helpful page with clear navigation options.

9. Payment Failure

Few errors are as stressful for a user as a failed payment. This is a high-stakes moment where clarity and reassurance are paramount. The Payment Failure pattern focuses on diagnosing the issue transparently and making it easy to fix.

  • When to use it: When a credit card is declined, a bank transfer fails, or any other payment method does not go through.

  • Copy best practices: Avoid generic "Payment failed" messages. Be as specific as the payment gateway allows: "Your card was declined. Please check the expiration date" or "Insufficient funds." Always provide an easy way to try again with a different card or method.

  • Visual example: An inline error message right next to the payment form fields, highlighting the specific field that needs attention. This is a critical error state ui design moment.

10. Rate Limiting

"You are doing that too fast. Please slow down." Rate Limiting errors occur when a user or script makes too many requests in a short period. This is a protective measure for your API, but it needs to be communicated clearly to the user to avoid confusion.

  • When to use it: When an API's rate limits are exceeded, often by automated scripts but sometimes by enthusiastic users.

  • Copy best practices: Be technical but clear. "API rate limit exceeded. Please wait 60 seconds before trying again." Linking to API documentation is a best practice.

  • Visual example: This is often an API response (like a 429 Too Many Requests status code), but if it needs a UI, it can be a modal or banner explaining the temporary block.

How to Map All Possible Error States

Seeing the patterns is one thing. How do you find where to apply them?

The truth is that most teams don't systematically map their failure states. It’s an afterthought. This is an economic mistake. A single unhandled error that makes it to production can cost 50-100x more to fix than if it were caught in the design phase. The zoom-out moment is realizing that good error design isn't a cost center, it's a massive risk-reduction strategy.

Your goal is to build a "failure state map" for every critical user flow.

  1. Deconstruct the Flow: Take a user journey, like "upload a file." Break it into every single user action and system response.

  2. Ask "What If?": For each step, brainstorm potential failures. What if the file is too large? What if it's the wrong format? What if the network drops mid-upload? (See Dropbox's upload failure states for inspiration).

  3. Assign a Pattern: For each potential failure, assign one of the ten patterns from this article.

  4. Document and Design: Create a design spec for each state. What is the copy? What is the visual treatment? What are the actions?

This process can feel tedious, but it’s the only way to build truly resilient software. Tools like Figr are built for this. Figr surfaces error states you haven't designed for. When you map a user flow, Figr identifies failure scenarios from 200k+ real UX patterns: network drops, permission errors, timeout states, payment failures. It catches the edge cases your team hasn't thought of.

How to Test Error States Systematically

A design spec is not a working product. Your beautiful error states are useless if they don't trigger correctly. Systematic testing is non-negotiable.

  • Manual Testing: QA engineers should have a checklist of error scenarios to trigger manually. This is the first line of defense.

  • Automated Testing: For regression, use tools like Cypress or Playwright to write scripts that simulate error conditions. This ensures that a new feature doesn't break an old error handler. You can learn more about this at our guide to UI automated testing.

  • Chaos Engineering: For complex systems, intentionally inject failures (like slowing down an API response) in a testing environment to see how the UI holds up.

In short, you must test for failure as rigorously as you test for success.

A Grounded Takeaway

We’ve journeyed through ten distinct error state design patterns, from simple inline messages to complex system failures. The throughline is empathy. You are showing the user that you foresaw this exact moment of friction and built a bridge to get them across it. Mastering this requires moving from knowledge to action.

Here is your next step.

Choose one, just one, critical user flow in your product. It could be sign-up, checkout, or creating a new document. Get your team in a room for 30 minutes and map every single thing that could go wrong. Use the patterns in this article as your guide. You will be amazed at what you uncover.

For the complete framework on this topic, see our guide to how to create test cases.

Ultimately, designing for failure is designing for humans. The products that win are not the ones that never fail, but the ones that fail with grace, clarity, and a clear path forward. Your users will not remember the error. They will remember how you helped them through it.

Product-aware AI that thinks through UX, then builds it
Edge cases, flows, and decisions first. Prototypes that reflect it. Ship without the rework.
Sign up for free
Published
April 1, 2026