Advent of A11Y 2025 is here!
Back to Advent Overview Dec 10, 2025

Helpful Error Messages

When someone makes a mistake in your form, don’t leave them guessing.

Too often, forms highlight errors with a red border and a vague message like “Invalid input.” That’s not helpful, especially for users with cognitive impairments or those using assistive technologies like screen readers.

Good error messages should:

  • clearly state what went wrong
  • tell the user how to fix it
  • appear next to the related field
  • be programmatically tied to that field
  • be announced automatically

Good Practice

  • Place error messages immediately after or near the field they refer to
  • Use plain, specific language. For example: “Please enter your email address” instead of “Invalid”
  • Tie errors to fields using aria-describedby or aria-errormessage
  • Mark invalid fields with aria-invalid="true"

Example:

<label for="email">Email address</label>
<input
  id="email"
  type="email"
  aria-describedby="email-error"
  aria-invalid="true"
/>
<p id="email-error" class="error" role="alert">
  Please enter a valid email address.
</p>

With this setup:

  • The input is marked invalid (aria-invalid=“true”)
  • The screen reader announces the error (aria-describedby links the field to the message)
  • The message is announced immediately (role=“alert”)

Watch Out For

  • Errors that are only visual (e.g., red border or icon with no text)
  • Messages that are not connected to their inputs
  • Using vague messages like “This field is required” without context
  • Not marking inputs as invalid (aria-invalid)

Bad Example:

<input type="text" placeholder="Email" />
<!-- visually red border, but no label or error text -->

Fix (as displayed above):

<label for="email">Email</label>
<input
  id="email"
  type="email"
  aria-describedby="email-error"
  aria-invalid="true"
/>
<p id="email-error" role="alert">Email is required.</p>

Pro Tip

Use aria-errormessage instead of (or alongside) aria-describedby for clearer semantics when the message only applies during an error state:

<input id="email" aria-invalid="true" aria-errormessage="email-error" />
<span id="email-error" role="alert"> Please enter a valid email. </span>

Bonus: Also focus the first invalid field on submit failure so users can fix things quickly.


Do this today: Try submitting an empty or invalid form on your site. Are errors clearly visible? Are they read aloud by screen readers? Do they tell the user how to fix the issue?

If not, add proper labels, associate messages programmatically, and use aria-invalid.

Stay in the loop!

Get to know some good resources. Once per month.

Frontend & Game Development, tools that make my life easier, newest blog posts and resources, codepens or some snippets. All for free!

No spam, just cool stuff. Promised. Unsubscribe anytime.