UX Design

Accessible Form Errors: Explain the Problem and Keep the Task Moving

By EZUD Published · Updated

Accessible Form Errors: Explain the Problem and Keep the Task Moving

An effective form error identifies the affected field, explains what went wrong and gives the user a workable correction. Keep valid entries, connect the message to the control and make the next action easy to find. Test the recovery path until the user can finish the original task.

Write error states when designing the form. Decide which checks happen in the browser, which require the server and which failures belong to the service rather than the entered data. That distinction determines both the message and the action you can reasonably ask the user to take.

Separate three kinds of failure

FailureWhat the interface should explainUseful next action
Missing or invalid inputWhich field needs attention and the accepted inputGo to the field and correct it
A business-rule conflictWhy the selected option is unavailableChoose another available option or edit the relevant choice
A service or connection problemWhat is known about the attempted actionRetry safely, check status or use the provided support route

Avoid marking a correct email address invalid because the server failed to respond. Keep the message at the level where the failure occurred. For an uncertain transaction outcome, provide a way to check its status before encouraging another submission that could duplicate the action.

Use the same field names as the visible labels. If the field is called “Delivery date,” the summary and inline message should use that name. Consistent wording helps people find the control visually, through links and through assistive technology.

Make the message specific and actionable

WCAG 3.3.1 requires an automatically detected input error to be identified and described in text. WCAG 3.3.3 addresses known suggestions for correction, with its stated security and purpose exception. A red outline alone does not explain the problem.

Compare these example messages:

Vague messageMore useful message
“Invalid value”“Enter the delivery date using day, month and year.”
“Upload failed”“Choose a PDF file smaller than the limit shown above.”
“Required”“Enter the email address for the booking confirmation.”
“Something went wrong”“Your changes were not saved. Keep this page open and try again.”

Use the final message only when the service knows that saving did not happen. Put actual formats, limits and available options into the implementation. Keep them synchronized with the server’s rules so following the instruction really does solve the problem.

Associate the inline message with the field

Place the message near the affected control. Preserve the label and any helpful instruction, then expose the invalid state and connect the error description. The following markup represents a field after validation has found a problem:

<label for="booking-email">Email address</label>
<p id="booking-email-hint">Use the address for your confirmation.</p>
<input id="booking-email" name="email" type="email"
       autocomplete="email" aria-invalid="true"
       aria-describedby="booking-email-hint booking-email-error">
<p id="booking-email-error">Enter an email address with a name and domain.</p>

Set the invalid state when an error is established. When the user resolves it, remove or update the error message and its relationship to the field. Retain the ordinary hint if it is still useful. Recheck that the visual state and the accessibility tree agree after each change.

Keep the error text readable at narrow widths and with zoom. Do not position it so that a longer translation overlaps another field. Test a message that wraps to several lines, because the shortest English example may conceal a layout problem.

Give multiple errors a navigable summary

When submission finds several problems, place a summary before the form with a clear heading and links to affected fields. Keep the inline messages as well so the explanation remains available when the user reaches the control.

For a dynamically updated form, decide how the summary is announced. One pattern is to make the summary focusable with tabindex="-1" and move focus there after the failed submission. Another notification pattern may suit a different flow. Test the chosen behavior so users receive a clear message without duplicate or competing announcements.

Make each link land on the corresponding control, and check the next Tab position. A summary that scrolls near a field while focus remains elsewhere can leave keyboard users uncertain about where to type. Confirm the behavior in the browsers and assistive technologies you support.

Choose validation timing that allows completion

Let people finish entering a value before presenting a format error that cannot yet be judged. A date or email address is incomplete during normal typing. Showing a failure after every character can add noise without helping the user correct anything.

Use submission, field exit or another appropriate point for the relevant check, then test the resulting experience. If a server check runs asynchronously, prevent an older response from overwriting the result for a newer value. Keep the message attached to the value that was actually checked.

Preserve valid entries after a failed submission. For a multi-step form, keep the user’s earlier work when they return to correct a later field. Explain any data that must be re-entered and make the relevant step easy to reach.

Handle waiting and success clearly

While saving, communicate that the action is in progress and prevent accidental duplicate operations in a way consistent with the service’s behavior. A status region can announce an update without moving focus when that suits the task. Keep the control’s name and state understandable throughout the operation.

When the request succeeds, give a specific confirmation. State whether the result is saved, submitted for review or fully completed. Include a reference or next step when the service provides one, and make that information available as ordinary readable content.

When the request fails, keep the user’s work and explain a practical path forward. Include a support route for a persistent problem and enough context for the user to describe the issue without exposing sensitive information. Keep internal stack traces and implementation codes out of the main message.

Retest the recovery path

Test an empty required field, a malformed value, several simultaneous errors, a corrected value, a delayed response and a server failure. Include keyboard operation, zoom and screen-reader use. Confirm that the user can identify the problem, reach the control, correct it and complete the task.

Record both the initial failure and the successful recovery. If a shared form component changes, repeat the cases on pages with different layouts and validation rules. Keeping these scenarios with the component prevents the next visual redesign from silently removing a working error relationship.

Sources