Fallback Patterns
User Experience During Failures
Read aloud is unavailable in this browser.
Failures Are Moments of Truth
In 2018, Slack experienced a widespread outage during peak business hours. Millions of users couldn't access their workspaces. But instead of a generic error page, users were greeted by a whimsical illustration and a message: 'There's been a bit of a hiccup. Our team is on the case.' The status page updated every few minutes with honest progress reports. Twitter filled with appreciative comments—not about the outage, but about how Slack handled it.
Contrast this with countless services that show cryptic 'Error 500' messages, leave users wondering if the problem is on their end, or go silent while users panic about lost data.
How you treat users during failures defines your relationship with them. Technical failures are inevitable; poor user experience during those failures is a choice.
This page provides comprehensive coverage of user experience design during system failures. You'll learn how to craft error messages that help rather than frustrate, when to communicate transparently and when to handle degradation silently, how to maintain user trust during extended outages, and how to design experiences that turn failure moments into trust-building opportunities.
The Psychology of Errors
Before designing error experiences, we must understand how users psychologically process failures. User reactions to errors follow predictable patterns that we can design for.
User error psychology:
- •Self-blame instinct — Users often assume errors are their fault. 'Did I do something wrong?' This is especially true for ambiguous error messages. Clear communication that the problem is system-side prevents unnecessary user guilt and frustration.
- •Loss anxiety — When something fails, users immediately worry about data loss. 'Is my work saved?' 'Did my payment go through?' Address data safety explicitly when possible.
- •Control-seeking behavior — When users lose control (can't complete their task), they seek any sense of agency. Provide alternatives, retry options, or at minimum, information about when they can try again.
- •Time perception distortion — Waiting during uncertainty feels much longer than it is. A 30-second wait with no feedback feels like minutes. Progress indicators and time estimates significantly reduce perceived wait time.
- •Attribution and blame — Users assign blame based on limited information. Poor error messaging leads to brand damage even when the issue is outside your control (network issues, third-party failures).
- •Trust erosion — Each unexplained or frustrating failure erodes trust. Multiple failures without good communication can create lasting negative perception resistant to recovery.
The trust equation during failures:
Trust = (Transparency + Reliability + Intimacy) / Self-Orientation
During failures, transparency becomes critically important. Users forgive failures more readily when they understand what's happening, why, and what's being done about it. Opacity breeds suspicion and frustration.
Emotional design considerations:
Error states trigger emotional responses—frustration, anxiety, confusion. Good error UX acknowledges these emotions and works to resolve them:
- Use empathetic language ('We know this is frustrating')
- Provide reassurance ('Your data is safe')
- Offer agency ('Here's what you can do')
- Set expectations ('We're working on this and expect resolution within an hour')
Research shows that users who participate in resolving issues value the outcome more highly. Giving users even small actions during failures (refresh, try alternative, check back later) can increase satisfaction compared to purely passive waiting.
Error Message Design
Error messages are the primary communication channel during failures. A well-designed error message reduces frustration, maintains trust, and enables user action. A poor error message compounds the failure with confusion.
Anatomy of an effective error message:
- •What happened — A plain-language description of the problem. Not technical jargon ('API timeout'), but user-understandable ('We couldn't load your messages').
- •Whose fault it is — Make it clear this is not the user's error (when applicable). 'We're having technical difficulties' takes responsibility.
- •Impact statement — What does this mean for the user? 'You won't be able to send messages until this is resolved.'
- •Reassurance — Address the user's likely fears. 'Your draft is saved. Your messages won't be lost.'
- •What they can do — Provide actionable next steps. 'Try again in a few minutes' or 'Use our mobile app as an alternative'.
- •Where to get more info — Link to status page, help center, or support for users who need more details.
| Bad Message | Why It's Bad | Good Message |
|---|---|---|
| Error 500 | Technical jargon, no explanation | Something went wrong on our end. We're working on it. |
| Request failed | Ambiguous, could be user's fault | We couldn't complete your request due to a system issue. |
| Null reference exception | Developer error leaked to user | We hit an unexpected problem. Our team has been notified. |
| Try again later | When is 'later'? What should they do now? | This usually resolves within 5 minutes. Try refreshing then. |
| Service unavailable | Which service? What does this mean? | We're doing some maintenance. Check [status page] for updates. |
Never expose: stack traces, internal service names, database errors, or debug information. This looks unprofessional, confuses users, and can be a security vulnerability. Log details internally; show human-friendly messages externally.
Transparency vs. Simplicity
A key tension in error UX is how much detail to share. Too little information (Error occurred) frustrates users seeking clarity. Too much information (Gateway timeout connecting to auth-service-replica-3) overwhelms and confuses.
The transparency spectrum:
| Audience | Detail Level | Example |
|---|---|---|
| Casual consumer user | Minimal - just impact and action | 'We're having trouble. Try again in a few minutes.' |
| Power user / Professional | Moderate - cause and workarounds | 'Our payment processor is slow. Your order is queued.' |
| Technical user / Developer | Detailed - can handle specifics | 'API rate limited. Retry after: 60s. See docs for limits.' |
| Internal user / Admin | Full - needs debugging info | 'Timeout: db-replica-2 (conn pool exhausted)' |
Progressive disclosure:
A powerful pattern is progressive disclosure—show simple information by default, with options to see more:
- Primary message: Simple, emotional, actionable ('Something went wrong')
- Secondary detail: Available on request ('Technical details' expandable)
- Full context: Link to status page for ongoing updates
This respects users who just want to know what to do, while serving power users who want to understand the issue.
When to be more transparent:
- Extended outages (users need updates)
- Data-sensitive issues (users worry about safety)
- Recurring problems (users deserve explanation)
- Enterprise/paying customers (expect more detail)
- Developer-facing APIs (need technical specifics)
When to simplify:
- Transient errors that self-resolve
- Errors during first-time user experience
- Complex technical causes users can't act on
- Highly stressful contexts (payment, booking)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
// React component for progressive error disclosurefunction ErrorMessage({ error, userType }: { error: SystemError; userType: UserType }) { const [showDetails, setShowDetails] = useState(false); // Always show: simple message + action const primaryContent = ( <div className="error-primary"> <h2>{error.userFriendlyTitle}</h2> <p>{error.userFriendlyMessage}</p> {error.suggestedAction && ( <button onClick={error.suggestedAction.handler}> {error.suggestedAction.label} </button> )} </div> ); // Available on request: more context const secondaryContent = showDetails && ( <div className="error-details"> <p><strong>What happened:</strong> {error.technicalSummary}</p> <p><strong>When:</strong> {formatTime(error.timestamp)}</p> <p><strong>Reference:</strong> {error.incidentId}</p> {userType === 'developer' && ( <pre className="error-trace">{error.debugInfo}</pre> )} </div> ); // Link to status for ongoing issues const statusLink = error.isOngoingIncident && ( <a href="/status" className="status-link"> Check system status for updates </a> ); return ( <div className="error-container"> {primaryContent} {error.hasDetails && ( <button className="show-details-toggle" onClick={() => setShowDetails(!showDetails)} > {showDetails ? 'Hide details' : 'Show details'} </button> )} {secondaryContent} {statusLink} </div> );}Status Pages and Communication
During significant outages, the error message alone isn't enough. Status pages provide a central source of truth for ongoing issues, reducing support burden and user anxiety.
Status page design principles:
- •Current status per component — Break down by service/feature. Not just 'site is down' but 'Checkout: Degraded, Account: Operational, Search: Degraded'.
- •Incident timeline — Show when the issue started, updates since, and current state. Users gauge progress from update frequency.
- •Plain-language updates — Avoid jargon. 'We've identified the issue and are deploying a fix' not 'Rolling back deployment after canary failure'.
- •Expected resolution time — Even estimates with wide ranges ('1-3 hours') are better than nothing. Update if estimates change.
- •User impact statement — What does this mean for users? 'You may experience slow page loads' is actionable information.
- •Subscription option — Let users subscribe to updates via email/SMS rather than refreshing constantly.
- •Historical uptime — Show past reliability. This builds trust: the current issue is an exception, not the norm.
Status communication cadence:
During active incidents, update frequency matters:
- First 15 minutes: Update every 5 minutes (even if just 'still investigating')
- 15-60 minutes: Update every 15 minutes
- 1+ hours: Update every 30 minutes minimum
- Multi-hour outages: Update every hour, with more detail
Silence is the worst option. An update that says 'No new information but still working on it' is better than no update.
Multi-channel communication:
Don't rely solely on your status page. During major incidents:
- In-app banners for users on your site
- Email for affected paying customers
- Twitter/social media for public visibility
- Embedded status widgets in your product
- Support staff briefed with talking points
Host your status page separately from your main infrastructure. If your primary infrastructure is down, your status page should still work. Services like Statuspage.io, Status.io, or self-hosted solutions on different infrastructure ensure status is available when you need it most.
In-Context Error UX
Errors can occur anywhere in the user journey. How you present errors in context—inline, modal, page-level—significantly impacts user experience and their ability to recover.
Error presentation patterns:
| Pattern | Best For | Example |
|---|---|---|
| Inline error | Specific field or action failures | Form field validation, individual item load failure |
| Toast notification | Non-blocking, transient errors | Background save failed, sync delayed |
| Banner | Site-wide or persistent issues | Degraded service mode, scheduled maintenance |
| Modal dialog | Blocking errors requiring acknowledgment | Session expired, payment failed |
| Full page | Complete failures, nothing else to show | Site down, critical error, 404 |
| Subtle indicator | Minor degradation user doesn't need to act on | 'Data may be delayed' icon, stale data indicator |
Preserving user work:
One of the most frustrating error experiences is losing work. Design error states that preserve user input:
- If a form submission fails, don't clear the form
- If a page can't save, auto-save to local storage
- If navigation fails, offer to stay on the current page
- If upload fails, don't discard the selected files
Error recovery actions:
Every error should offer a clear next step. Common recovery patterns:
- •Retry — Button to attempt the action again. Best for transient failures. Include automatic countdown ('Retrying in 5s...').
- •Alternative action — Suggest different approach. 'Payment failed. Try a different card or use PayPal.'
- •Escalation — Path to get help. 'Contact support' with context auto-filled.
- •Save for later — Don't lose the work. 'We couldn't submit now. Save draft and try later?'
- •Workaround — Temporary solution. 'Advanced search unavailable. Use basic search for now.'
- •Return to safety — Navigate to a working state. 'Return to homepage' when deep navigation fails.
For non-critical data, use optimistic saving: show success immediately, save in the background, and only surface errors if they persist after retries. Users get snappy UX, and transient failures are handled invisibly.
Communicating Degraded States
Degraded operation (not full failure) presents a communication challenge. The system works, just not optimally. How much should users know?
The communication decision matrix:
| Degradation Type | User Impact | Communicate? |
|---|---|---|
| Slower response times | Noticeable but functional | Only if extreme (>2x normal) |
| Stale data | Decisions based on data | Yes - show data age/freshness |
| Reduced personalization | Less relevant content | Usually no - subtle quality difference |
| Limited functionality | Can't do something | Yes - explain what's unavailable |
| Lower quality (images) | Visual difference | Usually no - unless very noticeable |
| Background sync delayed | Data not syncing | Yes - users need to know data state |
Principles for degradation communication:
-
Communicate when impact is actionable — If users should change their behavior (refresh more often, save manually, use alternative), tell them. If they can't do anything anyway, communication may just create anxiety.
-
Communicate when decisions are based on data — If users might make purchases, bookings, or other commitments based on data that's stale, they need to know.
-
Be subtle for cosmetic degradation — Slightly smaller images, missing animations, or generic rather than personalized content rarely need explicit callout. Users may not even notice.
-
Set expectations for recovery — If communicating degradation, include when normal operation is expected or how users will know it's resolved.
Degradation indicator patterns:
- •Timestamp indicators — 'Last updated 15 minutes ago' signals stale data without alarming users.
- •Freshness badges — Small icons (⚠️ or clock) next to data that's potentially stale.
- •Section headers — 'Showing cached results' instead of 'Search results'
- •Subtle banners — Thin, dismissable information bars for site-wide degradation
- •Tooltip explanations — Hover/tap reveals why something looks different
- •Implicit communication — 'Trending Products' instead of 'Recommended for You' signals generic content without explicit degradation messaging
Emotional Design During Failures
Failures create emotional responses: frustration, anxiety, confusion. Error design should intentionally address these emotions. This is emotional design—designing for how users feel, not just what they need to do.
Emotional design elements:
- •Empathetic language — Use words that acknowledge the user's situation. 'We know this is frustrating' validates their emotion. Avoid cold, robotic language.
- •Brand personality in errors — Maintain your brand voice even in errors. Slack's playful error pages, GitHub's octocat outage art—personality humanizes the error.
- •Visual softness — Error pages don't need to be harsh. Illustrations, softer colors, and approachable design reduce the sting of bad news.
- •Reassurance first — Lead with what's safe/working, not what's broken. 'Your data is safe. We're having trouble loading the page.' puts critical info first.
- •Avoid blame language — Never say 'You did something wrong' unless it's clearly a user input error. Even then, frame constructively.
- •Humor (when appropriate) — Light humor can defuse tension, but only for non-critical situations and only if it fits your brand. Never joke about data loss, payments, or security.
Matching emotional response to severity:
| Severity | Emotional Tone | Example |
|---|---|---|
| Minor glitch | Light, casual | 'Whoops! That didn't work. Try again?' |
| Feature unavailable | Understanding, helpful | 'This feature is temporarily unavailable. Here's an alternative...' |
| Major outage | Serious, accountable | 'We're experiencing significant issues. Our entire team is working on this.' |
| Data/Security concern | Serious, reassuring | 'Your account is secure. We detected an issue and are investigating.' |
| Extended outage | Apologetic, transparent | 'We apologize for the extended disruption. Here's what we know and what we're doing.' |
Avoid playful tone when: money is involved, data might be lost, security is in question, or the user is likely already anxious (healthcare, legal, financial products). Read the room—a cute error illustration is charming for a social app, inappropriate for a banking app.
KEEP LEARNING
There’s more to understand.
You’re reading the introduction. Create a free account to read the complete lesson, save notes and keep track of your progress.