← All Articles

Design for When Things Go Wrong

Design for When Things Go Wrong

Errors happen. They are... inevitable. In product design we want to protect the user from themselves, from making an error to begin with. But, it still happens.

A network connection fails. A payment gets declined. Someone enters info the system can't accept. APIs time out. A user will click the wrong button—or the interface will... eh, you get the idea. There are a thousand ways to error!

Good product design isn't about eliminating every error. It's about making errors preventable, understandable, and recoverable.

An error state is therefore more than a red message beneath an input. It is part of the product's conversation with the user at a moment when something has gone wrong.

The question isn't simply:

"How do we tell the user there is an error?"

A better question is:

"What does the user need to understand and do next?"

Start by preventing the error

The best error message is often the one the user never needs to see.

Before designing an error state, ask whether the interface can prevent the problem in the first place.

Good prevention might mean:

  • Constraining an input to acceptable values
  • Providing examples of the expected format
  • Using appropriate defaults
  • Making destructive actions harder to trigger accidentally
  • Disabling an action when it genuinely cannot succeed
  • Clearly communicating requirements before submission
  • Designing controls that make the intended action obvious
  • Providing contextual guidance before the user makes a mistake

This is particularly important because many apparent "user errors" are actually design problems.

A user who enters an unexpected date format may not have made a mistake in their mind. They may simply have been given an ambiguous field.

A user who deletes the wrong item may not have been careless. The destructive action may have been too easy to trigger or too visually similar to another action.

A user who repeatedly submits an invalid value may not be failing to understand the system. The system may be failing to explain what it expects.

Don't begin with the error message. Begin with the cause.

Not all errors are the same

Understanding what caused an error helps determine how the product should respond.

System errors

System errors originate within the technology or its dependencies:

  • A server is unavailable
  • A network connection is lost
  • An API fails
  • A request times out
  • A software defect produces an unexpected result
  • A third-party service is unavailable

The user may have done everything correctly.

These errors require particular care because blaming the user is both inaccurate and frustrating.

User slips

A slip occurs when the user's goal is correct but their action doesn't match their intention.

Examples include:

  • Clicking the wrong button
  • Entering the wrong value
  • Deleting an item accidentally
  • Acting in the wrong mode or context
  • Misreading a label
  • Submitting something too early

Slips are often good candidates for better interaction design. If users frequently make the same slip, don't simply improve the error message. Consider improving the interface.

User mistakes

A mistake is different. The user's action may be intentional, but their understanding or decision is wrong.

For example, a user might select the wrong option because they don't understand a domain-specific term.

That distinction matters.

If the user lacks information, giving them a better explanation may help. If the interface makes an action easy to misinterpret, changing the interface may be the better solution.

The goal isn't to make users better at recovering from bad design. The goal is to make bad design less necessary.

Three lines of defense

A useful way to think about error handling is as three layers:

  1. Prevent the error
  2. Validate as the user works
  3. Validate when the action is submitted

These layers work together.

1. Prevent

Help users make the correct choice before an error occurs.

2. Validate

When appropriate, identify problems as the user moves through a task so they can correct them before submission.

3. Confirm

The server or system still needs to validate the submitted information. Client-side validation is not a substitute for server-side validation.

This last point is important: an interface can tell a user that their information looks valid, but only the system processing the request can ultimately determine whether the operation succeeds.

Timing matters

An error message can be technically correct and still create a terrible experience if it appears at the wrong time.

Imagine typing an email address and seeing an error after every keystroke:

Invalid email.

The user hasn't finished typing.

The interface is technically validating the field, but it is creating unnecessary cognitive noise.

For many fields, a better approach is to validate after the user has finished interacting with the field—often when it loses focus. The internal guidance similarly recommends avoiding premature error messages and generally presenting validation after the field loses focus.

There are exceptions.

Some interactions benefit from immediate feedback. Others may need validation only when the user submits. The right timing depends on the task, the consequences of the error, and whether the user can reasonably act on the feedback while continuing.

The principle is simple:

Don't interrupt the user's thinking unless the feedback is useful at that moment.

Write errors for humans

A good error message answers at least one of these questions:

  • What happened?
  • What needs to change?
  • What can I do now?

Ideally, it answers all three.

Compare:

Invalid input.

with:

Enter a valid email address, such as name@example.com.

The second message gives the user something actionable.

Even better, if the system knows exactly what went wrong, explain that specific problem.

Instead of:

Incorrect information.

say:

Password must be between 8 and 64 characters.

Specificity reduces the amount of detective work the user has to do.

Avoid technical language

Users generally don't need to know that the application returned a 403, that a token expired, or that an API returned a particular exception.

Those details may be valuable to developers and support teams. They are usually not useful to the person trying to complete a task.

Instead of:

Error 401: Authentication token invalid

consider:

Your session has expired. Log in again to continue.

The underlying technical information can still be captured in logs and telemetry without forcing the user to interpret it.

Don't blame the user

Error messages should describe the situation, not criticize the person experiencing it.

Compare:

You entered an invalid ZIP code.

with:

Enter a valid 5-digit ZIP code.

The second version is more direct and more useful.

It also avoids making the interaction adversarial.

Likewise, avoid vague instructions such as:

Try again later.

Later when?

If the system knows something useful about the situation, say it. If it doesn't, provide the most useful next action available.

For example:

We couldn't connect to the server. Check your internet connection and try again.

Or:

We're having trouble processing your request. Try again in a few minutes. If the problem continues, contact support.

The goal isn't to apologize for every error. It is to help the user move forward.

Choose the right error pattern

Different problems deserve different levels of interruption.

Inline errors

Use inline validation when the problem belongs to a particular field.

The message should appear close to the thing that needs correction.

For example:

Email

[ name@example.com ]

Enter a valid email address.

This minimizes the user's effort to understand what needs attention.

Your internal guidance specifically recommends keeping field validation short, clear, and useful, with the message helping the user correct the problem.

Alert messages

Use an alert when an error affects the broader task rather than one particular field.

For example, if submitting a form fails because the server cannot process the request, putting an error message above the form may be more appropriate than attaching the message to an arbitrary field.

Error summaries

Long forms can produce multiple errors.

Rather than forcing users to search through the entire page, provide a summary identifying the problems and, where appropriate, links to the affected fields.

An error summary is particularly useful when errors are distributed throughout a long form.

Modals interrupt whatever the user is doing.

That makes them powerful—and easy to misuse.

Use them when the problem genuinely requires immediate attention or when continuing without acknowledging the problem could cause significant harm or confusion.

Don't use a modal simply because an error is important.

An important error can often be communicated without stopping the user's entire workflow.

Full-page errors

Sometimes the page itself cannot function.

A 404 page is the familiar example, but authentication failures, unavailable services, and major system failures can also require a full-page treatment.

Even then, don't leave the user at a dead end.

Provide another useful path whenever possible:

  • Return to the previous page
  • Go to the home page
  • Search
  • View related content
  • Contact support
  • Retry the operation

An error page should be a detour, not a dead end.

Don't hide important errors in a toast

Toasts are useful for transient status information.

They are generally a poor place for errors that require the user to understand or act.

A toast can disappear before the user reads it. It can be missed entirely. It may be disconnected from the thing that needs correction.

If the user needs to take action, the error should generally remain visible and associated with that action.

The internal guidance explicitly recommends against using toast messages for important errors.

Preserve what the user already did

One of the most frustrating error experiences is being forced to start over.

If a form submission fails, preserve the user's input.

If an upload fails, don't necessarily make them rebuild the entire upload process.

If a session expires, preserve as much work as safely possible.

The user shouldn't have to pay for a system failure with additional work.

This is especially important for long or complex workflows.

Recovery should cost as little as possible.

Don't make users fix what they didn't break

Consider a form with ten fields. The user fills out all ten and submits. The server returns an error unrelated to any individual field.

Don't clear the form.

Don't send the user back to the beginning.

Don't make them repeat successful work.

Likewise, if a system error occurs after an expensive or time-consuming operation, consider whether the operation can be safely retried or resumed.

Good error handling preserves progress.

Give people examples

When the format of an input matters, examples can be more effective than abstract instructions.

Instead of:

Invalid format

try:

Enter time in HH:MM format.

Or:

Enter a phone number, such as 602-123-4567.

Examples reduce the amount of interpretation required.

But don't use examples as a substitute for clear requirements. If a field accepts a range of values, explain the actual rule.

Be careful with validation

Validation exists to protect data quality and help users complete a task. It shouldn't become a barrier for its own sake.

Overly restrictive validation can create its own class of errors.

For example, an address field may reject a perfectly legitimate address because it doesn't conform to the assumptions built into the validation rules.

When the system can safely accept an unusual value, consider allowing it rather than forcing the user into an artificial format.

The internal guidance calls this out explicitly: where validation is overzealous or misses a legitimate use case, an override can sometimes prevent unnecessary abandonment.

Validation should protect the system without unnecessarily constraining the user.

Accessibility isn't an add-on

An error that is obvious visually may be completely invisible to someone using assistive technology.

A field shouldn't communicate its error state through color alone.

For example, don't rely solely on a red border.

Use multiple cues:

  • Text
  • Icons where appropriate
  • Color
  • Programmatic relationships
  • Appropriate focus behavior

The field should expose its error state programmatically, and the associated error message should be connected to the field so assistive technologies can understand the relationship. Your internal guidance recommends aria-invalid, aria-describedby, and appropriate live-region behavior for communicating these states.

Accessibility also means considering keyboard users when errors appear.

If a form produces several errors, an error summary with links to the affected fields can provide a much more efficient way to navigate the problem.

Don't automatically throw users around the page

Automatically scrolling a user to an error can be useful, especially on a long form.

But sudden movement can also be disorienting.

If you need to move the user's attention, do it deliberately and predictably.

For complex forms, a useful pattern is:

  1. Show an error summary.
  2. Tell the user how many problems need attention.
  3. Provide links to the affected fields.
  4. Move focus appropriately.
  5. Preserve the user's position and work wherever possible.

The goal is to help the user find the problem, not to make the interface move unexpectedly.

Repeated errors are a design signal

One of the most valuable things an error state can tell a product team is that the interface itself may need improvement.

If users repeatedly encounter the same error, don't simply make the error message longer.

Ask:

  • Why are users making this mistake?
  • Is the requirement clear?
  • Can we prevent the error?
  • Is the field asking for information users don't have?
  • Is the validation too restrictive?
  • Is the control confusing?
  • Is the workflow creating an unexpected mental model?
  • Are users abandoning the task?

Error metrics can become product-quality metrics.

Track things such as:

  • Frequency of errors
  • Repeated errors
  • Error recovery time
  • Form completion rate
  • Task abandonment
  • Successful completion after an error

A high error rate isn't necessarily evidence that users need better instructions.

It may be evidence that the product needs better design.

A simple framework for designing an error state

When you're designing an error state, walk through these questions:

1. Can we prevent this?

If yes, fix the experience rather than relying on error messaging.

2. Who or what caused the problem?

Is this a system failure, a slip, a misunderstanding, or something else?

Don't automatically classify it as "user error."

3. When should the user be told?

During interaction? On blur? At submission? Immediately?

4. Where should the message appear?

Next to the field? Above the form? In an alert? On a dedicated page?

5. What does the user need to know?

Explain the problem in plain language.

6. What can the user do?

Give them a specific, logical next action.

7. Can they recover without losing work?

Preserve their input and progress.

8. Can everyone perceive the error?

Make the state accessible without relying on color alone.

9. What happens if they encounter it again?

Repeated errors should be a signal to reconsider the design, not merely an opportunity to repeat the same message.

The best error experience is a recovery experience

Error handling is sometimes treated as the least glamorous part of interface design.

It shouldn't be.

Errors are moments when the user's confidence in a product is most vulnerable. A vague message, a disappearing toast, a cleared form, or a technical error code tells the user: you're on your own now.

A well-designed error state says something very different:

Here's what happened. Here's what matters. Here's what you can do next.

That's the real purpose of error messaging.

Not to announce that something went wrong.

To help the user get back on track.