design hubs
On this page
Microcopy
5 min read

Error Messages

An error message is the last line of help before the user gives up. It must say what went wrong, why, and exactly how to fix it — without blame, jargon, or vague reassurance.

Error messages appear at the worst possible moment: when something has gone wrong, the user’s task is interrupted, and their frustration is beginning to build. The content of an error message determines whether the user recovers from that moment and completes their task, or abandons it. This makes error message writing some of the most consequential content work in an interface.

The anatomy of a useful error message

A useful error message does three things:

  1. Says what went wrong — specifically, not generally. “Invalid input” is not an explanation. “Your email address needs an @ sign” is.

  2. Explains why, if it is not obvious — some errors need context. “This email address is already in use” tells the user what happened. “Sign in instead, or reset your password if you’ve forgotten it” tells them what to do about it.

  3. Tells them how to fix it — every error message should end with the user knowing their next action. This might be “Check your connection and try again,” “Make sure your password has at least 8 characters,” or “Try a different file format — we accept PDF and DOCX.”

What error messages must not do

Blame the user. “You entered an invalid password” is blame. “The password doesn’t match — try again or reset it” is help. The distinction is subtle but consistent: passive constructions that locate the error with the user (“you entered,” “you forgot”) frame errors as the user’s fault. Active constructions that locate the error with the system or the situation frame them as problems to be solved.

Use system language. “Error 403: Forbidden,” “Null pointer exception,” “HTTP 500 Internal Server Error” are system language. They mean something to developers; they mean nothing to users and often cause more distress than the error itself. All user-facing errors should be written in plain English (or whatever the user’s language is).

Be vague in the name of being polite. “Something went wrong” is the most commonly used and least useful error message in existence. It tells the user nothing about what happened or what to do. Vagueness is not kindness; it is an obstacle. When the cause of an error is genuinely unknown (“Something went wrong” is sometimes accurate — the system had an unexpected failure), the message should still give the user a path forward: “Something went wrong — try again, or contact support if this keeps happening.”

Placement matters

Error message content is only half the design. Placement is equally important. An error message that appears at the top of a page, away from the field it refers to, requires the user to read the error, find the field, and remember the correction while navigating back to it. An inline error that appears directly below the field it describes requires none of that effort.

For form validation, the convention is clear: inline error messages, positioned directly below the field, appearing either immediately on blur (as soon as the user leaves a field) or on submission. Inline errors are faster to act on and less cognitively demanding than summary error panels.

Timing

Validation timing is a content design decision: show errors immediately when the user leaves a field (eager validation), or wait until the user tries to submit the form (deferred validation). The trade-offs are real.

Eager validation catches errors early and reduces submission failures, but can feel intrusive if error messages appear before the user has finished typing. Deferred validation is less intrusive but shows all errors at once after a failed submission, which can feel overwhelming.

The emerging best practice is hybrid: validate on blur (when the user leaves a field), but do not show inline errors while the user is typing. This catches errors as each field is completed, without interrupting the user mid-keystroke.

Accessible error messages

Error messages that are visually clear can still be inaccessible to users who navigate by keyboard or screen reader. Three requirements apply:

Association — the error message must be programmatically linked to the field it describes. Placing an error below a field visually is not sufficient; the error text must be connected via aria-describedby on the input element so screen readers announce it when the user focuses the field. An unlinked error message is invisible to a screen reader user who is navigating between fields.

Announcement — when a form submission fails, the new error messages injected into the DOM must be announced. Either move keyboard focus to the first errored field, move it to a summary error message at the top of the form, or use an aria-live="assertive" region to announce the error count (“3 errors. Please correct the highlighted fields before continuing”). Errors that appear silently in the DOM — visible to sighted users but not announced — leave screen reader users at a failed submission with no indication of what happened.

Identification — required fields must be identifiable before the user submits. The required attribute causes screen readers to announce the field as required on focus. Indicating required fields only with a visual asterisk, without programmatic support, fails screen reader users who are completing the form for the first time.

For the complete implementation pattern see focus management and accessible forms in the Interaction hub.

The next section on content models starts with what content models are — the structural thinking that turns writing into a system.

Practice

0 / 3

Keyboard shortcuts

Show shortcuts
?
Search
CtrlK
Previous article
Next article
Close
Esc