Error States Pattern
Errors are inevitable. How you handle them determines whether users can recover gracefully or give up in frustration. This document covers patterns for communicating errors and helping users move forward.
Last updated: November 2024
Error design principles
Be honest
Acknowledge what went wrong. Don't hide errors or use vague language hoping users won't notice.
Be specific
Generic errors don't help. "Something went wrong" gives users nothing to work with. Tell them what specifically happened.
Be helpful
Every error should suggest a path forward. What can users do to fix or work around the problem?
Be human
Error messages are stressful moments. Use a calm, clear, supportive tone. Avoid technical jargon and blame.
Preserve work
Never lose user input due to an error. If a form submission fails, the user's entries should still be there when they return.
Types of errors
Validation errors
User input doesn't meet requirements.
Design approach:
- Show immediately (on blur or submission)
- Position near the problematic field
- Explain exactly what's wrong
- Show how to fix it
Good example: "Email address must include @ and a domain (e.g., [email protected])"
Bad example: "Invalid input"
Permission errors
User can't do what they're trying to do.
Design approach:
- Explain why the action isn't available
- Offer alternatives if they exist
- Suggest who can help if appropriate
Good example: "You don't have permission to edit this document. Ask [Owner Name] for access."
Bad example: "403 Forbidden"
System errors
Something technical went wrong.
Design approach:
- Acknowledge the problem honestly
- Don't expose technical details unless relevant
- Offer retry if appropriate
- Provide support contact for persistent issues
Good example: "We couldn't save your changes due to a connection issue. Your work is saved locally. Try again?"
Bad example: "Error code 5xx: Internal server failure at cluster node 3"
Connection errors
Network issues prevent completion.
Design approach:
- Distinguish from other errors (it's not the user's fault)
- Offer offline functionality if available
- Provide automatic retry with manual option
- Show when connection returns
Good example: "You appear to be offline. We'll sync your changes when you reconnect."
Not found errors (404)
Requested content doesn't exist.
Design approach:
- Confirm what they were looking for
- Suggest where it might have moved
- Provide navigation to main areas
- Include search if available
A good 404 page prevents complete dead-ends. Include search, popular links, and a way to report broken links. Some users arrive via old links—help them find what they need.
Error message anatomy
A complete error message includes:
- What happened: Clear statement of the problem
- Why it happened: Brief explanation (if helpful)
- What to do: Specific action to resolve
- Alternatives: Other paths forward if the main action can't be completed
Example structure
Can't upload file
The file is larger than 10MB. Try compressing it or use a different file.
[Choose different file] [Learn about file limits]
Visual design of errors
Color
- Red is conventional for errors
- Don't rely on color alone (accessibility)
- Ensure sufficient contrast
- Use consistently across the product
Icons
- Error/warning icons provide additional signal
- Use consistently (⚠️ for warnings, ✕ or ⊘ for errors)
- Position with the message text
Positioning
- Inline errors: Next to the problematic element
- Toast/snackbar: For system-level errors or confirmation failures
- Modal: For critical errors requiring immediate attention (use sparingly)
- Full-page: For complete failures (404, major system errors)
Motion
- Gentle attention-drawing (subtle shake, fade in)
- Don't use aggressive, startling animations
- Respect reduced-motion preferences
Form error patterns
Inline field errors
Position: Below the field or to the side Timing: On blur or on submit (not on every keystroke) Content: Specific to what's wrong with that field
<label for="email">Email</label>
<input id="email" aria-describedby="email-error" aria-invalid="true">
<span id="email-error" class="error">Please enter a valid email address</span>
Error summary
For forms with multiple errors:
- Show summary at top of form
- Link each summary item to its field
- Focus the summary after submission
<div role="alert" aria-labelledby="error-summary-heading">
<h2 id="error-summary-heading">There were 2 problems with your submission</h2>
<ul>
<li><a href="#email">Email address is invalid</a></li>
<li><a href="#password">Password must be at least 8 characters</a></li>
</ul>
</div>
Error states on buttons
When a form action fails:
- Keep button enabled (allow retry)
- Show error message near button
- Preserve all valid input
System error patterns
Toast notifications
When to use: Errors that don't block continued use.
Best practices:
- Position consistently (often top-right or bottom)
- Persist until dismissed (don't auto-dismiss errors)
- Include retry action if applicable
Error modals
When to use: Critical errors requiring acknowledgment.
Best practices:
- Use sparingly—modals disrupt flow
- Clear title stating the problem
- Focused action (usually "OK" or "Try again")
- Don't trap users—allow closing without action when possible
Error pages
When to use: Complete failures (no content can load).
Best practices:
- Maintain navigation if possible
- Provide ways back to working parts of the product
- Include support contact for critical issues
- Add personality appropriately (but don't make light of frustration)
Preventing errors
Better than handling errors is preventing them:
Smart defaults
- Pre-fill with likely values
- Set reasonable limits that most users won't hit
- Suggest valid inputs
Clear constraints
- Show requirements before input (password rules, file limits)
- Show character counts approaching limits
- Disable impossible actions rather than allowing them to fail
Confirmation for destructive actions
- "Are you sure you want to delete?" before permanent deletion
- Show what will be affected
- Provide undo where possible
Forgiving inputs
- Accept multiple formats (phone numbers, dates)
- Auto-correct obvious typos
- Normalize input (trim whitespace, fix capitalization)
Where possible, make actions reversible rather than requiring confirmation. "Deleted. [Undo]" is faster than "Are you sure?" and creates less friction while still allowing recovery.
Error recovery
Preserve state
Never lose user data. If a long form fails to submit:
- Keep all entered values
- Highlight only what needs fixing
- Allow correction and resubmission
Offer alternatives
If the requested action isn't possible:
- Suggest similar actions that might work
- Provide contact for human help
- Allow saving work in progress
Clear the error state
When users fix the problem:
- Remove error styling immediately
- Show success confirmation
- Allow them to proceed
Accessibility requirements
- Use
role="alert"for dynamically appearing errors - Associate errors with fields via
aria-describedby - Mark invalid fields with
aria-invalid="true" - Ensure errors are announced to screen readers
- Don't use color as the only indicator
- Ensure focus moves appropriately (to error summary or first error)
Generally no—it's annoying to see errors before you're done typing. Validate on blur (when leaving the field) or on submission. Exception: helpful guidance (character counts, password strength) can appear while typing.
As specific as possible without security implications. 'Password must include a number' is better than 'Invalid password.' But 'This email is registered' might reveal account existence—consider security context.
Rarely. Modals interrupt flow. Use them for critical, unexpected errors requiring immediate attention—not for routine validation or recoverable issues.
Prevent errors at each step when possible. When errors occur at submission of multiple steps, take users back to the problematic step with clear indication of what needs fixing.
Log errors on the backend for debugging. Track error frequency and patterns. If many users hit the same error, improve the design to prevent it—not just the message to explain it.