Skip to main content

Form elements - Error summary

Include an error summary at the top of a page to summarise any mistakes a user has made.

Open this error summary example in new window
Copy
<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">
    <p>
      Describe the errors and how to correct them
    </p>
    <ul class="nhsuk-list nhsuk-error-summary__list">
      <li>
        <a href="#example-error-1">Date of birth must be in the past</a>
      </li>
      <li>
        <a href="#example-error-1">Enter a postcode, like AA1 1AA</a>
      </li>
    </ul>
  </div>
</div>
Copy
{% from 'error-summary/macro.njk' import errorSummary %}

{{ errorSummary({
  "titleText": "There is a problem",
  "descriptionText": "Describe the errors and how to correct them",
  "errorList": [
    {
      "text": "Date of birth must be in the past",
      "href": "#example-error-1"
    },
    {
      "text": "Enter a postcode, like AA1 1AA",
      "href": "#example-error-1"
    }
  ]
}) }}

When to use an error summary

When a user makes a mistake, you must show an error summary at the top of the page as well as an error message next to each answer that contains an error.

Always show an error summary when there is a validation error, even if there’s only 1 mistake.

How to use an error summary

You must:

  • add "Error: " to the beginning of the <title> so screen readers read it out as soon as possible
  • show an error summary at the top of a page
  • move the keyboard focus to the error summary
  • include the heading "There is a problem"
  • link to each of the answers that have validation errors
  • show the same error messages next to the inputs with errors

Follow GOV.UK Design System guidance on:

Linking from the error summary to each answer

You must link the errors in the error summary to the answer they relate to.

For questions that require a user to answer using a single field, like a file upload, select, textarea, text input or character count, link to the field.

Open this error summary link input example in new window
Copy
<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">
      <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>
Copy
{% from 'error-summary/macro.njk' import errorSummary %}
{% from 'input/macro.njk' import input %}

{{ 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"
  }
}) }}

When a user has to enter their answer into multiple fields, such as the day, month and year fields in the date input component, link to the 1st field that contains an error.

If you do not know which field contains an error, link to the 1st field.

Open this error summary link multiple input example in new window
Copy
<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">
      <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>
    <span class="nhsuk-hint" id="dob-errors-hint">
      For example, 15 3 1984
    </span>

    <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="number" value="15" pattern="[0-9]*">
        </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="number" value="3" pattern="[0-9]*">
        </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="number" pattern="[0-9]*">
        </div>
      </div>
    </div>
  </fieldset>

</div>
Copy
{% from 'error-summary/macro.njk' import errorSummary %}
{% from 'date-input/macro.njk' import dateInput %}

{{ 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"
    }
  ]
}) }}

For questions that require a user to select one or more options from a list using radios or checkboxes, link to the 1st radio or checkbox.

Open this error summary link options example in new window
Copy
<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">
      <li>
        <a href="#contact">Select how you like to be contacted</a>
      </li>
    </ul>
  </div>
</div>

<div class="nhsuk-form-group nhsuk-form-group--error">

  <fieldset class="nhsuk-fieldset" aria-describedby="contact-hint contact-error">
    <legend class="nhsuk-fieldset__legend nhsuk-fieldset__legend--l">
      <h1 class="nhsuk-fieldset__heading">
        How would you like to be contacted?
      </h1>
    </legend>

    <span class="nhsuk-hint" id="contact-hint">
      Select all options that are relevant to you.
    </span>

    <span class="nhsuk-error-message" id="contact-error">
      <span class="nhsuk-u-visually-hidden">Error:</span> Select how you like to be contacted
    </span>

    <div class="nhsuk-checkboxes">

      <div class="nhsuk-checkboxes__item">
        <input class="nhsuk-checkboxes__input" id="contact" name="contact" type="checkbox" value="email">
        <label class="nhsuk-label nhsuk-checkboxes__label" for="contact">
          Email
        </label>
      </div>

      <div class="nhsuk-checkboxes__item">
        <input class="nhsuk-checkboxes__input" id="contact-2" name="contact" type="checkbox" value="phone">
        <label class="nhsuk-label nhsuk-checkboxes__label" for="contact-2">
          Phone
        </label>
      </div>

      <div class="nhsuk-checkboxes__item">
        <input class="nhsuk-checkboxes__input" id="contact-3" name="contact" type="checkbox" value="text message">
        <label class="nhsuk-label nhsuk-checkboxes__label" for="contact-3">
          Text message
        </label>
      </div>

    </div>
  </fieldset>

</div>
Copy
{% from 'error-summary/macro.njk' import errorSummary %}
{% from 'checkboxes/macro.njk' import checkboxes %}

{{ errorSummary({
  "titleText": "There is a problem",
  "errorList": [
    {
      "text": "Select how you like to be contacted",
      "href": "#contact"
    }
  ]
}) }}

{{ checkboxes({
  "idPrefix": "contact",
  "name": "contact",
  "fieldset": {
    "legend": {
      "text": "How would you like to be contacted?",
      "classes": "nhsuk-fieldset__legend--l",
      isPageHeading: true
    }
  },
  "hint": {
    "text": "Select all options that are relevant to you."
  },
  "errorMessage": {
    "text": "Select how you like to be contacted"
  },
  "items": [
    {
      "value": "email",
      "text": "Email",
      id: "contact"
    },
    {
      "value": "phone",
      "text": "Phone"
    },
    {
      "value": "text message",
      "text": "Text message"
    }
  ]
}) }}

Where to put the error summary

Put the error summary at the top of the main container. If your page includes breadcrumbs or a back link, place it below these, but above the <h1>.

Open this error summary placement example in new window
Copy
<div class="nhsuk-width-container">

  <div class="nhsuk-back-link nhsuk-u-margin-bottom-0 nhsuk-u-margin-top-4">
    <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">
        <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="main-content" 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">
                <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>
              <span class="nhsuk-hint" id="dob-errors-hint">
                For example, 15 3 1984
              </span>

              <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="number" value="15" pattern="[0-9]*">
                  </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="number" value="3" pattern="[0-9]*">
                  </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="number" pattern="[0-9]*">
                  </div>
                </div>
              </div>
            </fieldset>

          </div>

          <button class="nhsuk-button" type="submit">
            Continue
          </button>

        </form>
      </div>
    </div>

  </main>
</div>
Copy
{% 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",
    "classes": "nhsuk-u-margin-bottom-0 nhsuk-u-margin-top-4"
  }) }}
{% 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 %}

Research

GOV.UK research on error summaries showed users:

  • understood what went wrong
  • knew how to fix the problem
  • were able to recover from the error

Help improve this page

The manual is a community effort. Anyone can help improve and grow it.

To help make sure the Error summary guidance is useful, relevant and up to date, you can:

Need help?

If you’ve got a question about the NHS digital service manual or want to feedback, you can contact the team:

Help improve the service manual

We’d welcome your feedback. Can you answer some questions about your visit today?

Updated: February 2020