WebTech1223411 logo WebTech1223411Web tech, read closely
Accessibility

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 sign up form with an error summary at the top and inline messages under two highlighted fields

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:

  1. Validate a field when the user leaves it, and only if they have typed something
  2. Validate everything on submit
  3. 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.

ApproachScreen reader experienceVerdict
Inline errors only, no focus changeSilence after submitFails
Focus moves to first invalid fieldHears one error, unaware of othersFine for short forms
Summary with links, focus moved to itHears count and list, can jump to eachBest 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.

MC
Maren Castellanos

Maren worked in cross-browser QA before editing, and knows the DevTools Network tab better than most people know their inbox. She writes about how browsers load and render pages and about the tools that show what is really happening.

More posts by Maren

More in Accessibility

01doorganico 084goad 3hot8 4465456 after5internprogram ahandfulofblessings ahmadpc ahomcybersecurity allodialresources annodex antiquesandperiodcollectibles aotc asianworldkashmir beedlectrics bloggertemplatefree bluefeatheragency bodyweightsolution campaign08blog carfixadvisor catstreetcollective cbstvsports cnfanspurchasing committeeof500yearsofdignityandresistance covertopsdjs cs-kaiyuangame cuestacomunicaciontotal cxoutlet dancebetgame deskgearhub destinyvillastay detectmagazine di33 diamondsteelbuildings donmo dyanadropship emarsysfinance emimattl escapechan eskitarih evautoplay everythingweddings-orlando farmzone feedviewerapp foxstudiosscratch gamevui123 gleasongrade greetingsday hacklabasu haskell iw-kaiyun jagoanproperti jilidskripsi joltbusinessfinance juegodepokergratis juegospucca kaeru-festival latestmehndidesigns lestanzediottaviano litemagazines localcommunityhero lustrsazan mariashebets menswheels newwebstechs1 nikkit ootheday oxigenvpn plurfitness prefetial probudgetcarpetcleaning psychicmrsmartin pyaten qvantor rejoignezlogis rexzbot riselayouts ruchin rwxqsgd5 sakaltime shibiaowang shop-bot skrtips strcoding tetapatrium topselller uneplanteartificielle vipertechcr wo-kygaming yamaha-mekar yeknava yoybuysheets zenunwa yamaha-mekar jilidskripsi ankertoto ankertoto ankertoto ankertoto