Form elements - Error message

Use an error message when there is a validation error. Explain what went wrong and how to fix it.

Open this in context error message example in new window
Copy in context error message code
<div class="hs2-form-group hs2-form-group--error">
  <fieldset class="hs2-fieldset" aria-describedby="dob-day-error-hint dob-day-error-error" role="group">
    <legend class="hs2-fieldset__legend hs2-fieldset__legend--l">
      <h1 class="hs2-fieldset__heading">
        What is your date of birth?
      </h1>
    </legend>
    <div class="hs2-hint" id="dob-day-error-hint">
      For example, 31 3 1980
    </div>

    <span class="hs2-error-message" id="dob-day-error-error">
      <span class="hs2-u-visually-hidden">Error:</span> Date of birth must be in the past
    </span>

    <div class="hs2-date-input" id="dob-day-error">
      <div class="hs2-date-input__item">
        <div class="hs2-form-group">
          <label class="hs2-label hs2-date-input__label" for="dob-day-error-day">
            Day
          </label>
          <input class="hs2-input hs2-date-input__input hs2-input--width-2 hs2-input--error" id="dob-day-error-day" name="dob-day-error-day" type="text" value="15" pattern="[0-9]*" inputmode="numeric">
        </div>
      </div>
      <div class="hs2-date-input__item">
        <div class="hs2-form-group">
          <label class="hs2-label hs2-date-input__label" for="dob-day-error-month">
            Month
          </label>
          <input class="hs2-input hs2-date-input__input hs2-input--width-2 hs2-input--error" id="dob-day-error-month" name="dob-day-error-month" type="text" value="3" pattern="[0-9]*" inputmode="numeric">
        </div>
      </div>
      <div class="hs2-date-input__item">
        <div class="hs2-form-group">
          <label class="hs2-label hs2-date-input__label" for="dob-day-error-year">
            Year
          </label>
          <input class="hs2-input hs2-date-input__input hs2-input--width-4 hs2-input--error" id="dob-day-error-year" name="dob-day-error-year" type="text" value="2084" pattern="[0-9]*" inputmode="numeric">
        </div>
      </div>
    </div>
  </fieldset>

</div>
Close in context error message code
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.

Nunjucks arguments for in context error message
Name Type Required Description
Name text Type string Required true Description 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.
Name html Type string Required true Description 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.
Name id Type string Required false Description Id attribute to add to the error message span tag.
Name classes Type string Required false Description Classes to add to the error message span tag.
Name attributes Type object Required false Description HTML attributes (for example data attributes) to add to the error message span tag.
Copy in context error message code
{% 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": "hs2-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": "hs2-input--width-2 hs2-input--error",
      value: 15
      },
      {
      "name": "month",
      "classes": "hs2-input--width-2 hs2-input--error",
      value: 3
      },
      {
      "name": "year",
      "classes": "hs2-input--width-4 hs2-input--error",
      value: 2084
      }
  ]
  }) }}
Close in context error message code

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

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

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".

Copy default error message code
<span class="hs2-error-message">
  <span class="hs2-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.

Open this radios error message example in new window
Copy radios error message code
<div class="hs2-form-group hs2-form-group--error">

  <fieldset class="hs2-fieldset" aria-describedby="example-error-hint example-error-error">
    <legend class="hs2-fieldset__legend hs2-fieldset__legend--l">
      <h1 class="hs2-fieldset__heading">
        Have you changed your name?
      </h1>
    </legend>

    <div class="hs2-hint" id="example-error-hint">
      This includes changing your last name or spelling your name differently.
    </div>

    <span class="hs2-error-message" id="example-error-error">
      <span class="hs2-u-visually-hidden">Error:</span> Select yes if you have changed your name
    </span>

    <div class="hs2-radios">

      <div class="hs2-radios__item">
        <input class="hs2-radios__input" id="example-error-1" name="example-error" type="radio" value="yes">
        <label class="hs2-label hs2-radios__label" for="example-error-1">
          Yes
        </label>
      </div>

      <div class="hs2-radios__item">
        <input class="hs2-radios__input" id="example-error-2" name="example-error" type="radio" value="no">
        <label class="hs2-label hs2-radios__label" for="example-error-2">
          No
        </label>
      </div>

    </div>
  </fieldset>

</div>
Close radios error message code
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.

Nunjucks arguments for radios error message
Name Type Required Description
Name text Type string Required true Description 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.
Name html Type string Required true Description 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.
Name id Type string Required false Description Id attribute to add to the error message span tag.
Name classes Type string Required false Description Classes to add to the error message span tag.
Name attributes Type object Required false Description HTML attributes (for example data attributes) to add to the error message span tag.
Copy radios error message code
{% 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": "hs2-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"
    }
  ]
}) }}
Close radios error message code

If you're using a label

This is how we use an error message with a label, for example, with text input.

Open this input error message example in new window
Copy input error message code
<div class="hs2-form-group hs2-form-group--error">
  <label class="hs2-label" for="example">
    Full name
  </label>
  <span class="hs2-error-message" id="example-error">
    <span class="hs2-u-visually-hidden">Error:</span> Enter your full name
  </span>
  <input class="hs2-input hs2-input--error" id="example" name="example" type="text" aria-describedby="example-error">
</div>
Close input error message code
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.

Nunjucks arguments for input error message
Name Type Required Description
Name text Type string Required true Description 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.
Name html Type string Required true Description 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.
Name id Type string Required false Description Id attribute to add to the error message span tag.
Name classes Type string Required false Description Classes to add to the error message span tag.
Name attributes Type object Required false Description HTML attributes (for example data attributes) to add to the error message span tag.
Copy input error message code
{% from 'input/macro.njk' import input %}

{{ input({
  "label": {
    "text": "Full name"
  },
  "id": "example",
  "name": "example",
  "errorMessage": {
    "text": "Enter your full name"
  }
}) }}
Close input error message code

Using an error summary

Summarise all errors at the top of the page the user is on using an error summary. For example:

Open this error summary placement error message example in new window
Copy error summary placement error message code
<div class="hs2-width-container">
  <div class="hs2-back-link hs2-u-margin-bottom-0 hs2-u-margin-top-4">
    <a class="hs2-back-link__link" href="#">
      <svg class="hs2-icon hs2-icon__chevron-left" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" height="24" width="24">
        <path d="M6.69995 6.82499L8.59995 8.69999L6.62495 10.675L21.325 10.675L21.325 13.325L6.62495 13.325L8.59995 15.3L6.69995 17.175L1.54995 12L6.69995 6.82499Z" />
      </svg>
      Go back</a>
  </div>

  <main class="hs2-main-wrapper" id="maincontent" role="main">
    <div class="hs2-grid-row">
      <div class="hs2-grid-column-two-thirds">
        <form>

          <div class="hs2-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
            <h2 class="hs2-error-summary__title" id="error-summary-title">
              There is a problem
            </h2>
            <div class="hs2-error-summary__body">
              <ul class="hs2-list hs2-error-summary__list">
                <li>
                  <a href="#dob-errors-year">Date of birth must include a year</a>
                </li>
              </ul>
            </div>
          </div>

          <div class="hs2-form-group hs2-form-group--error">
            <fieldset class="hs2-fieldset" aria-describedby="dob-errors-hint dob-errors-error" role="group">
              <legend class="hs2-fieldset__legend hs2-fieldset__legend--l">
                <h1 class="hs2-fieldset__heading">
                  What is your date of birth?
                </h1>
              </legend>
              <div class="hs2-hint" id="dob-errors-hint">
                For example, 15 3 1984
              </div>

              <span class="hs2-error-message" id="dob-errors-error">
                <span class="hs2-u-visually-hidden">Error:</span> Date of birth must include a year
              </span>

              <div class="hs2-date-input" id="dob-errors">
                <div class="hs2-date-input__item">
                  <div class="hs2-form-group">
                    <label class="hs2-label hs2-date-input__label" for="dob-errors-day">
                      Day
                    </label>
                    <input class="hs2-input hs2-date-input__input hs2-input--width-2" id="dob-errors-day" name="day" type="text" value="15" pattern="[0-9]*" inputmode="numeric">
                  </div>
                </div>
                <div class="hs2-date-input__item">
                  <div class="hs2-form-group">
                    <label class="hs2-label hs2-date-input__label" for="dob-errors-month">
                      Month
                    </label>
                    <input class="hs2-input hs2-date-input__input hs2-input--width-2" id="dob-errors-month" name="month" type="text" value="3" pattern="[0-9]*" inputmode="numeric">
                  </div>
                </div>
                <div class="hs2-date-input__item">
                  <div class="hs2-form-group">
                    <label class="hs2-label hs2-date-input__label" for="dob-errors-year">
                      Year
                    </label>
                    <input class="hs2-input hs2-date-input__input hs2-input--width-4 hs2-input--error" id="dob-errors-year" name="year" type="text" pattern="[0-9]*" inputmode="numeric">
                  </div>
                </div>
              </div>
            </fieldset>

          </div>

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

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

  </main>
</div>
Close error summary placement error message code
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.

Nunjucks arguments for error summary placement error message
Name Type Required Description
Name text Type string Required true Description 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.
Name html Type string Required true Description 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.
Name id Type string Required false Description Id attribute to add to the error message span tag.
Name classes Type string Required false Description Classes to add to the error message span tag.
Name attributes Type object Required false Description HTML attributes (for example data attributes) to add to the error message span tag.
Copy error summary placement error message code
{% 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": "hs2-u-margin-bottom-0 hs2-u-margin-top-4"
  }) }}
{% endblock %}

{% block content %}
  <div class="hs2-grid-row">
    <div class="hs2-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": "hs2-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": "hs2-input--width-2",
              value: 15
            },
            {
              "name": "month",
              "classes": "hs2-input--width-2",
              value: 3
            },
            {
              "name": "year",
              "classes": "hs2-input--width-4 hs2-input--error"
            }
          ]
        }) }}

        {{ button({
          "text": "Continue"
        }) }}

      </form>
    </div>
  </div>
{% endblock %}
Close error summary placement error message code
Open this error summary placement input error message example in new window
Copy error summary placement input error message code
<div class="hs2-width-container">
  <div class="hs2-back-link hs2-u-margin-bottom-0 hs2-u-margin-top-4">
    <a class="hs2-back-link__link" href="#">
      <svg class="hs2-icon hs2-icon__chevron-left" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" height="24" width="24">
        <path d="M6.69995 6.82499L8.59995 8.69999L6.62495 10.675L21.325 10.675L21.325 13.325L6.62495 13.325L8.59995 15.3L6.69995 17.175L1.54995 12L6.69995 6.82499Z" />
      </svg>
      Go back</a>
  </div>

  <main class="hs2-main-wrapper" id="maincontent" role="main">
    <div class="hs2-grid-row">
      <div class="hs2-grid-column-two-thirds">
        <form>

          <div class="hs2-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
            <h2 class="hs2-error-summary__title" id="error-summary-title">
              There is a problem
            </h2>
            <div class="hs2-error-summary__body">
              <ul class="hs2-list hs2-error-summary__list">
                <li>
                  <a href="#name">Enter your full name</a>
                </li>
              </ul>
            </div>
          </div>

          <h1 class="hs2-heading-l">Your details</h1>

          <div class="hs2-form-group hs2-form-group--error">
            <label class="hs2-label" for="name">
              Full name
            </label>
            <span class="hs2-error-message" id="name-error">
              <span class="hs2-u-visually-hidden">Error:</span> Enter your full name
            </span>
            <input class="hs2-input hs2-input--error" id="name" name="name" type="text" aria-describedby="name-error">
          </div>

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

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

  </main>
</div>
Close error summary placement input error message code
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.

Nunjucks arguments for error summary placement input error message
Name Type Required Description
Name text Type string Required true Description 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.
Name html Type string Required true Description 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.
Name id Type string Required false Description Id attribute to add to the error message span tag.
Name classes Type string Required false Description Classes to add to the error message span tag.
Name attributes Type object Required false Description HTML attributes (for example data attributes) to add to the error message span tag.
Copy error summary placement input error message code
{% 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",
    "classes": "hs2-u-margin-bottom-0 hs2-u-margin-top-4"
  }) }}
{% endblock %}

{% block content %}
  <div class="hs2-grid-row">
    <div class="hs2-grid-column-two-thirds">
      <form>

        {{ errorSummary({
          "titleText": "There is a problem",
          "errorList": [
            {
              "text": "Enter your full name",
              "href": "#name"
            }
          ]
        }) }}

        <h1 class="hs2-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 %}
Close error summary placement input error message code
Open this error summary placement multiple error message example in new window
Copy error summary placement multiple error message code
<div class="hs2-width-container">
  <div class="hs2-back-link hs2-u-margin-bottom-0 hs2-u-margin-top-4">
    <a class="hs2-back-link__link" href="#">
      <svg class="hs2-icon hs2-icon__chevron-left" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" height="24" width="24">
        <path d="M6.69995 6.82499L8.59995 8.69999L6.62495 10.675L21.325 10.675L21.325 13.325L6.62495 13.325L8.59995 15.3L6.69995 17.175L1.54995 12L6.69995 6.82499Z" />
      </svg>
      Go back</a>
  </div>

  <main class="hs2-main-wrapper" id="maincontent" role="main">
    <div class="hs2-grid-row">
      <div class="hs2-grid-column-two-thirds">
        <form>

          <div class="hs2-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
            <h2 class="hs2-error-summary__title" id="error-summary-title">
              There is a problem
            </h2>
            <div class="hs2-error-summary__body">
              <ul class="hs2-list hs2-error-summary__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="hs2-heading-l">Your details</h1>

          <div class="hs2-form-group hs2-form-group--error">
            <label class="hs2-label" for="first-name">
              First name
            </label>
            <span class="hs2-error-message" id="first-name-error">
              <span class="hs2-u-visually-hidden">Error:</span> Enter your first name
            </span>
            <input class="hs2-input hs2-input--error" id="first-name" name="first-name" type="text" aria-describedby="first-name-error">
          </div>

          <div class="hs2-form-group hs2-form-group--error">
            <label class="hs2-label" for="last-name">
              Last name
            </label>
            <span class="hs2-error-message" id="last-name-error">
              <span class="hs2-u-visually-hidden">Error:</span> Enter your last name
            </span>
            <input class="hs2-input hs2-input--error" id="last-name" name="last-name" type="text" aria-describedby="last-name-error">
          </div>

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

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

  </main>
</div>
Close error summary placement multiple error message code
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.

Nunjucks arguments for error summary placement multiple error message
Name Type Required Description
Name text Type string Required true Description 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.
Name html Type string Required true Description 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.
Name id Type string Required false Description Id attribute to add to the error message span tag.
Name classes Type string Required false Description Classes to add to the error message span tag.
Name attributes Type object Required false Description HTML attributes (for example data attributes) to add to the error message span tag.
Copy error summary placement multiple error message code
{% 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",
    "classes": "hs2-u-margin-bottom-0 hs2-u-margin-top-4"
  }) }}
{% endblock %}

{% block content %}
  <div class="hs2-grid-row">
    <div class="hs2-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="hs2-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 %}
Close error summary placement multiple error message code

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. Read more about writing good error messages on GOV.UK.

Use standard messages for different components. The GOV.UK Design System has some good 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