Use an error message when there is a validation error. Explain what went wrong and how to fix it.
WCAG 2.2 affects this component
To meet new success criteria introduced in the Web Content Accessibility Guidelines (WCAG) 2.2, make sure that users can successfully:
See the full list of design system changes to meet WCAG 2.2.
<div class="nhsuk-form-group nhsuk-form-group--error">
<fieldset class="nhsuk-fieldset" aria-describedby="dob-day-error-hint dob-day-error-error" role="group">
<legend class="nhsuk-fieldset__legend nhsuk-fieldset__legend--l">
<h1 class="nhsuk-fieldset__heading">
What is your date of birth?
</h1>
</legend>
<div class="nhsuk-hint" id="dob-day-error-hint">
For example, 31 3 1980
</div>
<span class="nhsuk-error-message" id="dob-day-error-error">
<span class="nhsuk-u-visually-hidden">Error:</span> Date of birth must be in the past
</span>
<div class="nhsuk-date-input" id="dob-day-error">
<div class="nhsuk-date-input__item">
<div class="nhsuk-form-group">
<label class="nhsuk-label nhsuk-date-input__label" for="dob-day-error-day">
Day
</label>
<input class="nhsuk-input nhsuk-date-input__input nhsuk-input--width-2 nhsuk-input--error" id="dob-day-error-day" name="dob-day-error[day]" type="text" value="15" inputmode="numeric">
</div>
</div>
<div class="nhsuk-date-input__item">
<div class="nhsuk-form-group">
<label class="nhsuk-label nhsuk-date-input__label" for="dob-day-error-month">
Month
</label>
<input class="nhsuk-input nhsuk-date-input__input nhsuk-input--width-2 nhsuk-input--error" id="dob-day-error-month" name="dob-day-error[month]" type="text" value="3" inputmode="numeric">
</div>
</div>
<div class="nhsuk-date-input__item">
<div class="nhsuk-form-group">
<label class="nhsuk-label nhsuk-date-input__label" for="dob-day-error-year">
Year
</label>
<input class="nhsuk-input nhsuk-date-input__input nhsuk-input--width-4 nhsuk-input--error" id="dob-day-error-year" name="dob-day-error[year]" type="text" value="2084" inputmode="numeric">
</div>
</div>
</div>
</fieldset>
</div>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
text | string | true | If `html` is set, this is not required. Text to use within the error message. If `html` is provided, the `text` argument will be ignored. |
html | string | true | If `text` is set, this is not required. HTML to use within the error message. If `html` is provided, the `text` argument will be ignored. |
id | string | false | Id attribute to add to the error message span tag. |
classes | string | false | Classes to add to the error message span tag. |
attributes | object | false | HTML attributes (for example data attributes) to add to the error message span tag. |
{% from 'error-message/macro.njk' import errorMessage %}
{% from 'date-input/macro.njk' import dateInput %}
{{ dateInput({
id: "dob-day-error",
namePrefix: "dob-day-error",
fieldset: {
legend: {
text: "What is your date of birth?",
classes: "nhsuk-fieldset__legend--l",
isPageHeading: true
}
},
hint: {
text: "For example, 31 3 1980"
},
errorMessage: {
text: "Date of birth must be in the past"
},
items: [
{
name: "day",
classes: "nhsuk-input--width-2 nhsuk-input--error",
value: 15
},
{
name: "month",
classes: "nhsuk-input--width-2 nhsuk-input--error",
value: 3
},
{
name: "year",
classes: "nhsuk-input--width-4 nhsuk-input--error",
value: 2084
}
]
}) }}
When to use error messages
Use the error message component when there is a validation error. For example when:
- you need to tell the user to choose an option before continuing
- you need the user to correct or change their input to match what your system can accept
Follow our guidance on how to write good questions for forms and make them easy to use so that users never see an error message.
When not to use error messages
Only display an error when someone tries to move to the next part of the service. Do not show error messages:
- when users select or tab to a field
- as they are typing
- when they move away from a field
Do not use error messages to tell users that they are not eligible or do not have permission to do something. Instead, take them to a screen that:
- explains why you cannot accept the entry or selection
- tells them what to do next
- includes a way to leave the transaction
How to use error messages
For each error:
- put the message in an error summary at the top of the page the user is on — linking to the answer that has the validation error
- put the message in red after the question text and hint text
- use a red border to visually connect the message and the question it belongs to
- if the error relates to specific text fields in the question, give these a red border as well
Do not clear any form fields when adding error messages. This is to comply with WCAG 2.2 success criterion 3.3.7 Redundant Entry (W3C).
Keeping information that caused errors helps users to:
- see what went wrong
- edit their previous answer
- avoid re-entering information
To help screen reader users, the error message component includes a hidden "Error:" before the error message. These users will hear, for example, "Error: Date of birth must be in the past".
<span class="nhsuk-error-message">
<span class="nhsuk-u-visually-hidden">Error:</span> Date of birth must be in the past
</span>
If you're using a legend
This is how we use an error message with a legend, for example with radios or checkboxes.
<div class="nhsuk-form-group nhsuk-form-group--error">
<fieldset class="nhsuk-fieldset" aria-describedby="example-error-hint example-error-error">
<legend class="nhsuk-fieldset__legend nhsuk-fieldset__legend--l">
<h1 class="nhsuk-fieldset__heading">
Have you changed your name?
</h1>
</legend>
<div class="nhsuk-hint" id="example-error-hint">
This includes changing your last name or spelling your name differently.
</div>
<span class="nhsuk-error-message" id="example-error-error">
<span class="nhsuk-u-visually-hidden">Error:</span> Select yes if you have changed your name
</span>
<div class="nhsuk-radios">
<div class="nhsuk-radios__item">
<input class="nhsuk-radios__input" id="example-error-1" name="example-error" type="radio" value="yes">
<label class="nhsuk-label nhsuk-radios__label" for="example-error-1">
Yes
</label>
</div>
<div class="nhsuk-radios__item">
<input class="nhsuk-radios__input" id="example-error-2" name="example-error" type="radio" value="no">
<label class="nhsuk-label nhsuk-radios__label" for="example-error-2">
No
</label>
</div>
</div>
</fieldset>
</div>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
text | string | true | If `html` is set, this is not required. Text to use within the error message. If `html` is provided, the `text` argument will be ignored. |
html | string | true | If `text` is set, this is not required. HTML to use within the error message. If `html` is provided, the `text` argument will be ignored. |
id | string | false | Id attribute to add to the error message span tag. |
classes | string | false | Classes to add to the error message span tag. |
attributes | object | false | HTML attributes (for example data attributes) to add to the error message span tag. |
{% from 'radios/macro.njk' import radios %}
{{ radios({
idPrefix: "example-error",
name: "example-error",
errorMessage: {
text: "Select yes if you have changed your name"
},
fieldset: {
legend: {
text: "Have you changed your name?",
classes: "nhsuk-fieldset__legend--l",
isPageHeading: true
}
},
hint: {
text: "This includes changing your last name or spelling your name differently."
},
items: [
{
value: "yes",
text: "Yes"
},
{
value: "no",
text: "No"
}
]
}) }}
If you're using a label
This is how we use an error message with a label, for example, with text input.
<div class="nhsuk-form-group nhsuk-form-group--error">
<label class="nhsuk-label" for="example">
Full name
</label>
<span class="nhsuk-error-message" id="example-error">
<span class="nhsuk-u-visually-hidden">Error:</span> Enter your full name
</span>
<input class="nhsuk-input nhsuk-input--error" id="example" name="example" type="text" aria-describedby="example-error">
</div>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
text | string | true | If `html` is set, this is not required. Text to use within the error message. If `html` is provided, the `text` argument will be ignored. |
html | string | true | If `text` is set, this is not required. HTML to use within the error message. If `html` is provided, the `text` argument will be ignored. |
id | string | false | Id attribute to add to the error message span tag. |
classes | string | false | Classes to add to the error message span tag. |
attributes | object | false | HTML attributes (for example data attributes) to add to the error message span tag. |
{% from 'input/macro.njk' import input %}
{{ input({
label: {
text: "Full name"
},
id: "example",
name: "example",
errorMessage: {
text: "Enter your full name"
}
}) }}
Using an error summary
Summarise all errors at the top of the page the user is on using an error summary. For example:
- HTML code for error summary placement error message
- Nunjucks code for error summary placement error message
<div class="nhsuk-width-container">
<div class="nhsuk-back-link">
<a class="nhsuk-back-link__link" href="#">
<svg class="nhsuk-icon nhsuk-icon__chevron-left" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" height="24" width="24">
<path d="M8.5 12c0-.3.1-.5.3-.7l5-5c.4-.4 1-.4 1.4 0s.4 1 0 1.4L10.9 12l4.3 4.3c.4.4.4 1 0 1.4s-1 .4-1.4 0l-5-5c-.2-.2-.3-.4-.3-.7z"></path>
</svg>
Go back</a>
</div>
<main class="nhsuk-main-wrapper" id="maincontent" role="main">
<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-two-thirds">
<form>
<div class="nhsuk-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
<h2 class="nhsuk-error-summary__title" id="error-summary-title">
There is a problem
</h2>
<div class="nhsuk-error-summary__body">
<ul class="nhsuk-list nhsuk-error-summary__list" role="list">
<li>
<a href="#dob-errors-year">Date of birth must include a year</a>
</li>
</ul>
</div>
</div>
<div class="nhsuk-form-group nhsuk-form-group--error">
<fieldset class="nhsuk-fieldset" aria-describedby="dob-errors-hint dob-errors-error" role="group">
<legend class="nhsuk-fieldset__legend nhsuk-fieldset__legend--l">
<h1 class="nhsuk-fieldset__heading">
What is your date of birth?
</h1>
</legend>
<div class="nhsuk-hint" id="dob-errors-hint">
For example, 15 3 1984
</div>
<span class="nhsuk-error-message" id="dob-errors-error">
<span class="nhsuk-u-visually-hidden">Error:</span> Date of birth must include a year
</span>
<div class="nhsuk-date-input" id="dob-errors">
<div class="nhsuk-date-input__item">
<div class="nhsuk-form-group">
<label class="nhsuk-label nhsuk-date-input__label" for="dob-errors-day">
Day
</label>
<input class="nhsuk-input nhsuk-date-input__input nhsuk-input--width-2" id="dob-errors-day" name="day" type="text" value="15" inputmode="numeric">
</div>
</div>
<div class="nhsuk-date-input__item">
<div class="nhsuk-form-group">
<label class="nhsuk-label nhsuk-date-input__label" for="dob-errors-month">
Month
</label>
<input class="nhsuk-input nhsuk-date-input__input nhsuk-input--width-2" id="dob-errors-month" name="month" type="text" value="3" inputmode="numeric">
</div>
</div>
<div class="nhsuk-date-input__item">
<div class="nhsuk-form-group">
<label class="nhsuk-label nhsuk-date-input__label" for="dob-errors-year">
Year
</label>
<input class="nhsuk-input nhsuk-date-input__input nhsuk-input--width-4 nhsuk-input--error" id="dob-errors-year" name="year" type="text" inputmode="numeric">
</div>
</div>
</div>
</fieldset>
</div>
<button class="nhsuk-button" data-module="nhsuk-button" type="submit">
Continue
</button>
</form>
</div>
</div>
</main>
</div>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
text | string | true | If `html` is set, this is not required. Text to use within the error message. If `html` is provided, the `text` argument will be ignored. |
html | string | true | If `text` is set, this is not required. HTML to use within the error message. If `html` is provided, the `text` argument will be ignored. |
id | string | false | Id attribute to add to the error message span tag. |
classes | string | false | Classes to add to the error message span tag. |
attributes | object | false | HTML attributes (for example data attributes) to add to the error message span tag. |
{% from 'back-link/macro.njk' import backLink %}
{% from 'button/macro.njk' import button %}
{% from 'date-input/macro.njk' import dateInput %}
{% from 'error-summary/macro.njk' import errorSummary %}
{% block beforeContent %}
{{ backLink({
href: "#",
text: "Go back"
}) }}
{% endblock %}
{% block content %}
<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-two-thirds">
<form>
{{ errorSummary({
titleText: "There is a problem",
errorList: [
{
text: "Date of birth must include a year",
href: "#dob-errors-year"
}
]
}) }}
{{ dateInput({
id: "dob-errors",
fieldset: {
legend: {
text: "What is your date of birth?",
classes: "nhsuk-fieldset__legend--l",
isPageHeading: true
}
},
hint: {
text: "For example, 15 3 1984"
},
errorMessage: {
text: "Date of birth must include a year"
},
items: [
{
name: "day",
classes: "nhsuk-input--width-2",
value: 15
},
{
name: "month",
classes: "nhsuk-input--width-2",
value: 3
},
{
name: "year",
classes: "nhsuk-input--width-4 nhsuk-input--error"
}
]
}) }}
{{ button({
text: "Continue"
}) }}
</form>
</div>
</div>
{% endblock %}
- HTML code for error summary placement input error message
- Nunjucks code for error summary placement input error message
<div class="nhsuk-width-container">
<div class="nhsuk-back-link">
<a class="nhsuk-back-link__link" href="#">
<svg class="nhsuk-icon nhsuk-icon__chevron-left" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" height="24" width="24">
<path d="M8.5 12c0-.3.1-.5.3-.7l5-5c.4-.4 1-.4 1.4 0s.4 1 0 1.4L10.9 12l4.3 4.3c.4.4.4 1 0 1.4s-1 .4-1.4 0l-5-5c-.2-.2-.3-.4-.3-.7z"></path>
</svg>
Go back</a>
</div>
<main class="nhsuk-main-wrapper" id="maincontent" role="main">
<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-two-thirds">
<form>
<div class="nhsuk-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
<h2 class="nhsuk-error-summary__title" id="error-summary-title">
There is a problem
</h2>
<div class="nhsuk-error-summary__body">
<ul class="nhsuk-list nhsuk-error-summary__list" role="list">
<li>
<a href="#name">Enter your full name</a>
</li>
</ul>
</div>
</div>
<h1 class="nhsuk-heading-l">Your details</h1>
<div class="nhsuk-form-group nhsuk-form-group--error">
<label class="nhsuk-label" for="name">
Full name
</label>
<span class="nhsuk-error-message" id="name-error">
<span class="nhsuk-u-visually-hidden">Error:</span> Enter your full name
</span>
<input class="nhsuk-input nhsuk-input--error" id="name" name="name" type="text" aria-describedby="name-error">
</div>
<button class="nhsuk-button" data-module="nhsuk-button" type="submit">
Continue
</button>
</form>
</div>
</div>
</main>
</div>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
text | string | true | If `html` is set, this is not required. Text to use within the error message. If `html` is provided, the `text` argument will be ignored. |
html | string | true | If `text` is set, this is not required. HTML to use within the error message. If `html` is provided, the `text` argument will be ignored. |
id | string | false | Id attribute to add to the error message span tag. |
classes | string | false | Classes to add to the error message span tag. |
attributes | object | false | HTML attributes (for example data attributes) to add to the error message span tag. |
{% from 'back-link/macro.njk' import backLink %}
{% from 'button/macro.njk' import button %}
{% from 'error-summary/macro.njk' import errorSummary %}
{% from 'input/macro.njk' import input %}
{% block beforeContent %}
{{ backLink({
href: "#",
text: "Go back"
}) }}
{% endblock %}
{% block content %}
<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-two-thirds">
<form>
{{ errorSummary({
titleText: "There is a problem",
errorList: [
{
text: "Enter your full name",
href: "#name"
}
]
}) }}
<h1 class="nhsuk-heading-l">Your details</h1>
{{ input({
label: {
text: "Full name"
},
id: "name",
name: "name",
errorMessage: {
text: "Enter your full name"
}
}) }}
{{ button({
text: "Continue"
}) }}
</form>
</div>
</div>
{% endblock %}
- HTML code for error summary placement multiple error message
- Nunjucks code for error summary placement multiple error message
<div class="nhsuk-width-container">
<div class="nhsuk-back-link">
<a class="nhsuk-back-link__link" href="#">
<svg class="nhsuk-icon nhsuk-icon__chevron-left" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" height="24" width="24">
<path d="M8.5 12c0-.3.1-.5.3-.7l5-5c.4-.4 1-.4 1.4 0s.4 1 0 1.4L10.9 12l4.3 4.3c.4.4.4 1 0 1.4s-1 .4-1.4 0l-5-5c-.2-.2-.3-.4-.3-.7z"></path>
</svg>
Go back</a>
</div>
<main class="nhsuk-main-wrapper" id="maincontent" role="main">
<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-two-thirds">
<form>
<div class="nhsuk-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
<h2 class="nhsuk-error-summary__title" id="error-summary-title">
There is a problem
</h2>
<div class="nhsuk-error-summary__body">
<ul class="nhsuk-list nhsuk-error-summary__list" role="list">
<li>
<a href="#first-name">Enter your first name</a>
</li>
<li>
<a href="#last-name">Enter your last name</a>
</li>
</ul>
</div>
</div>
<h1 class="nhsuk-heading-l">Your details</h1>
<div class="nhsuk-form-group nhsuk-form-group--error">
<label class="nhsuk-label" for="first-name">
First name
</label>
<span class="nhsuk-error-message" id="first-name-error">
<span class="nhsuk-u-visually-hidden">Error:</span> Enter your first name
</span>
<input class="nhsuk-input nhsuk-input--error" id="first-name" name="first-name" type="text" aria-describedby="first-name-error">
</div>
<div class="nhsuk-form-group nhsuk-form-group--error">
<label class="nhsuk-label" for="last-name">
Last name
</label>
<span class="nhsuk-error-message" id="last-name-error">
<span class="nhsuk-u-visually-hidden">Error:</span> Enter your last name
</span>
<input class="nhsuk-input nhsuk-input--error" id="last-name" name="last-name" type="text" aria-describedby="last-name-error">
</div>
<button class="nhsuk-button" data-module="nhsuk-button" type="submit">
Continue
</button>
</form>
</div>
</div>
</main>
</div>
Nunjucks macro options
Use options to customise the appearance, content and behaviour of a component when using a macro, for example, changing the text.
Some options are required for the macro to work; these are marked as "Required" in the option description.
If you're using Nunjucks macros in production with "html" options, or ones ending with "html", you must sanitise the HTML to protect against cross-site scripting exploits.
Name | Type | Required | Description |
---|---|---|---|
text | string | true | If `html` is set, this is not required. Text to use within the error message. If `html` is provided, the `text` argument will be ignored. |
html | string | true | If `text` is set, this is not required. HTML to use within the error message. If `html` is provided, the `text` argument will be ignored. |
id | string | false | Id attribute to add to the error message span tag. |
classes | string | false | Classes to add to the error message span tag. |
attributes | object | false | HTML attributes (for example data attributes) to add to the error message span tag. |
{% from 'back-link/macro.njk' import backLink %}
{% from 'button/macro.njk' import button %}
{% from 'error-summary/macro.njk' import errorSummary %}
{% from 'input/macro.njk' import input %}
{% block beforeContent %}
{{ backLink({
href: "#",
text: "Go back"
}) }}
{% endblock %}
{% block content %}
<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-two-thirds">
<form>
{{ errorSummary({
titleText: "There is a problem",
errorList: [
{
text: "Enter your first name",
href: "#first-name"
},
{
text: "Enter your last name",
href: "#last-name"
}
]
}) }}
<h1 class="nhsuk-heading-l">Your details</h1>
{{ input({
label: {
text: "First name"
},
id: "first-name",
name: "first-name",
errorMessage: {
text: "Enter your first name"
}
}) }}
{{ input({
label: {
text: "Last name"
},
id: "last-name",
name: "last-name",
errorMessage: {
text: "Enter your last name"
}
}) }}
{{ button({
text: "Continue"
}) }}
</form>
</div>
</div>
{% endblock %}
How to write error messages
Focus on telling users how to fix the problem rather than describing what's gone wrong. You may need to write more than 1 error message for each field. See the GOV.UK error message component for more guidance on writing good error messages.
Use standard messages for different components. The GOV.UK error message component also includes error message templates for common errors.
Research
Research on error messages showed users:
- understood what went wrong
- knew how to fix the problem
- were able to recover from the error
Help us improve this guidance
Share insights or feedback and take part in the discussion. We use GitHub as a collaboration space. All the information on it is open to the public.
Read more about how to feedback or share insights.
If you have any questions, get in touch with the service manual team.
Updated: April 2024