Accessible Form Error Messages Screen Readers Announce
A user fills in a 12 field sign up form, presses submit, and the page reloads with two fields outlined in red. Sighted mouse users spot the problem in a second.

A user fills in a 12 field sign up form, presses submit, and the page reloads with two fields outlined in red. Sighted mouse users spot the problem in a second. A screen reader user hears nothing at all, tabs back through the form from the top, and gives up somewhere around field seven. Accessible form error messages are one of the most common gaps I find in audits, and also one of the cheapest to fix properly.
The fix is not a single attribute. It is a small set of decisions about when errors appear, where they live, and how they are announced. Here is the approach I use on client projects, with the mistakes that keep showing up.
Why Red Borders Are Not an Error Message
Colour alone fails at least three groups: screen reader users, who never see it; people with red green colour blindness, roughly 8 percent of men; and anyone on a phone outdoors in bright light. An accessible error needs text, close to the field, that says what is wrong and how to fix it.
"Invalid input" is text, but it is not a message. "Enter a date in the format DD/MM/YYYY" is. The best error messages repeat the rule the user broke and give an example.
Tone matters as well. Messages like "You forgot your postcode" or "Wrong password format" read as blame, and they tend to come from developers writing copy at the last minute. Phrase each one as an instruction instead: "Enter your postcode" or "Use at least 12 characters, including one number." Keep a short shared list of approved messages in the codebase so the same rule is described the same way on every form, which also makes translation far easier.
Connecting Accessible Form Error Messages to Their Fields
A visible message is only half the job. The screen reader needs to know which field the message belongs to. Three pieces work together:
- aria-invalid set to true on the field, so assistive technology announces it as invalid when focused
- aria-describedby on the field, pointing to the id of the error text, so the message is read after the label
- A real label element tied to the field, never a placeholder used as a label
When this is wired correctly, a screen reader user who tabs to the email field hears something like "Email, invalid entry, edit text, Enter an email address like name at example dot com." That one sentence replaces the visual scan a sighted user does.
Remove aria-invalid and clear the description once the field is fixed. Leaving stale error states is a surprisingly common bug, and it makes users doubt their correct answers.
When to Validate: On Submit, Not on Every Keystroke
A lot of form libraries default to validating as the user types, and plenty of UX articles recommend it as instant feedback. I push back on this hard. Live validation tells someone their email is invalid after they have typed the first letter. For screen reader users, an error announced on every keystroke is noise that drowns out what they are typing.
A calmer pattern works better for almost everyone:
- Validate a field when the user leaves it, and only if they have typed something
- Validate everything on submit
- Once a field has shown an error, re validate it as they type, so the error clears the moment it is fixed
That last step is the one place where live validation genuinely helps, because it confirms a fix rather than predicting a mistake.
Error Summaries and Focus After Submit
For any form longer than three or four fields, show an error summary at the top after a failed submit. Move keyboard focus to it, give it a heading such as "There are 2 problems with your form", and list each error as a link that jumps to the field.
| Approach | Screen reader experience | Verdict |
|---|---|---|
| Inline errors only, no focus change | Silence after submit | Fails |
| Focus moves to first invalid field | Hears one error, unaware of others | Fine for short forms |
| Summary with links, focus moved to it | Hears count and list, can jump to each | Best for long forms |
Also update the page title, for example by adding "Error:" at the start, when a server side submit reloads the page. Screen readers announce the title on load, so users know immediately that something went wrong.
Live Regions, Used Sparingly
An aria-live region announces content that changes without focus moving. It is tempting to wrap every error in one. Do not. Several live regions updating at once read over each other, and some screen readers queue them in odd orders.
Use a single polite live region for messages that are not tied to a field, such as "Saving failed, check your connection." For field errors, rely on aria-describedby and focus management instead. If you want to see how these choices actually sound, test with a real screen reader; the checks I describe in the keyboard navigation accessibility test most sites fail are a good warm up before you switch one on.
Testing Your Form Errors in Ten Minutes
Automated tools catch missing labels but rarely judge whether an error is announced at the right moment or makes sense. As covered in why automated accessibility scanners miss most real problems, this is exactly the kind of issue they miss. A quick manual pass:
- Submit the empty form using only the keyboard and listen for what is announced
- Tab to each invalid field and check that the error text is read
- Fix one error and confirm the invalid state clears
- Zoom the page to 200 percent and check that messages do not overlap fields
NVDA on Windows and VoiceOver on macOS are both free, and ten minutes with either will teach you more than any checklist.
FAQ
Should error messages appear above or below the field?
Either works if it is consistent and linked with aria-describedby. Below the label but above the input is slightly better on mobile, because the keyboard can cover text beneath the field.
Is the browser's built in validation accessible?
Partly. Native required and type checks are announced by most screen readers, but the default bubbles disappear quickly, cannot be styled, and their wording is generic. Most teams replace them with custom messages.
Do I still need server side validation?
Yes. Client side checks are for usability; the server must validate everything. Make sure server errors come back in the same accessible format as client errors.
The Practical Takeaway
Write messages that state the rule and an example, connect them with aria-describedby and aria-invalid, validate on blur and submit instead of every keystroke, and move focus to an error summary on long forms. Then test with a free screen reader for ten minutes. More practical fixes are in our accessibility section.
More in Accessibility
Accessibility
How to Write Alt Text That Helps Screen Reader Users
A screen reader user lands on your product page and hears "image, IMG_4471.jpg" three times in a row.
Accessibility
How to Add a Skip to Content Link That Actually Works
Press Tab on a typical news site and count how many times you hit a key before you reach the first headline.
Accessibility
Color Contrast Ratios Explained for Readable Web Text
The grey #777777 on a white background has a contrast ratio of 4.48 to 1.