> ## Documentation Index
> Fetch the complete documentation index at: https://holder.docs.fiskil.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Phase 3: Error validation

> Send invalid CDR data requests in UAT and confirm your Data Holder returns the correct CDS error codes and HTTP status codes.

In this phase, you send deliberately incorrect data requests and confirm the Data Holder returns the right error. Under the Consumer Data Standards (CDS), error responses must use specific HTTP status codes and error codes, and follow a set structure. For the full definitions, see [Error Codes](https://consumerdatastandardsaustralia.github.io/standards/#error-codes) in the CDS.

> [!NOTE]
>
> **Prerequisite:** Complete [Phase 2](https://holder.docs.fiskil.dev/api-reference/cdr/testing/data-validation.md) so you have working requests and a known-good response for each persona.

***

## Error response structure

Every error response contains an `errors` array. Each error has a `code`, a `title`, and a `detail`.

```json Example error response theme={null}
{
  "errors": [
    {
      "code": "urn:au-cds:error:cds-all:Field/InvalidPageSize",
      "title": "Invalid Page Size",
      "detail": "page-size must not exceed 1000"
    }
  ]
}
```

For each test, confirm:

* The HTTP status code matches the table below.
* The `code` matches the CDS error code exactly.
* The `detail` identifies the field, header, or resource ID at fault, where the CDS says it should, without revealing sensitive information.

***

## Quick reference

Start with these common scenarios, then work through the full list below.

| Status | Type | Error | How to trigger |
| - | - | - | - |
| `200` | OK | Successful response | Send a valid request with an active CDR arrangement |
| `400` | Bad Request | Invalid Field | Pass an invalid query parameter value |
| `400` | Bad Request | Invalid Page Size | Pass `page-size=1001` |
| `400` | Bad Request | Invalid Version | Pass a non-integer version header, such as `x-v=foo` |
| `404` | Not Found | Invalid Resource | Request a resource ID in the URL that doesn't exist for the customer |
| `406` | Not Acceptable | Unsupported Version | Pass a positive integer version you don't support, such as `x-v=99` |
| `422` | Unprocessable Entity | Invalid Page | Request a page beyond the last page, such as `page=999` |

***

## Error scenarios by status code

> **400 Bad Request**
>
> | Error | Error code | When it applies | How to trigger in UAT |
> | - | - | - | - |
> | [Missing Required Field](https://consumerdatastandardsaustralia.github.io/standards/#error-400-field-missing) | `urn:au-cds:error:cds-all:Field/Missing` | A mandatory query parameter or request body field is missing | Call `POST /banking/accounts/balances` with a body that omits `data.accountIds` |
> | [Missing Required Header](https://consumerdatastandardsaustralia.github.io/standards/#error-400-header-missing) | `urn:au-cds:error:cds-all:Header/Missing` | A required HTTP header isn't provided | Send a request without the `x-v` header |
> | [Invalid Field](https://consumerdatastandardsaustralia.github.io/standards/#error-400-field-invalid) | `urn:au-cds:error:cds-all:Field/Invalid` | A parameter has the wrong type or breaks its constraints | Call `GET /banking/accounts?is-owned=notaboolean` or `GET /energy/accounts?open-status=INVALID` |
> | [Invalid Header](https://consumerdatastandardsaustralia.github.io/standards/#error-400-header-invalid) | `urn:au-cds:error:cds-all:Header/Invalid` | A header is provided but its value has the wrong type or format | Send `x-fapi-auth-date` with a value that isn't a valid HTTP date |
> | [Invalid Date](https://consumerdatastandardsaustralia.github.io/standards/#error-400-field-invalid-date-time) | `urn:au-cds:error:cds-all:Field/InvalidDateTime` | A date, date-time, or time value is invalid | Call `GET /banking/accounts/{accountId}/transactions?oldest-time=2024-13-45T00:00:00Z` |
> | [Invalid Page Size](https://consumerdatastandardsaustralia.github.io/standards/#error-400-field-invalid-page-size) | `urn:au-cds:error:cds-all:Field/InvalidPageSize` | `page-size` is greater than 1000 | Pass `page-size=1001` on any paginated endpoint |
> | [Invalid Version](https://consumerdatastandardsaustralia.github.io/standards/#error-400-header-invalid-version) | `urn:au-cds:error:cds-all:Header/InvalidVersion` | `x-v` or `x-min-v` isn't a positive integer | Pass `x-v=foo` or `x-v=0` |

> **403 Forbidden**
>
> | Error | Error code | When it applies | How to trigger in UAT |
> | - | - | - | - |
> | [Consent Is Revoked](https://consumerdatastandardsaustralia.github.io/standards/#error-403-authorisation-revoked-consent) | `urn:au-cds:error:cds-all:Authorisation/RevokedConsent` | The consent is no longer authorised, for example because it was revoked or expired | Revoke a consent in [Phase 4](https://holder.docs.fiskil.dev/api-reference/cdr/testing/consent-dashboard.md), then call any data endpoint with that arrangement |
> | [Consent Is Invalid](https://consumerdatastandardsaustralia.github.io/standards/#error-403-authorisation-invalid-consent) | `urn:au-cds:error:cds-all:Authorisation/InvalidConsent` | The consent isn't associated with the resource, is insufficient for it, or is in a status that prevents it | Call an endpoint whose scope isn't in the consent, such as `GET /banking/payees` without `bank:payees:read` |

> **404 Not Found**
>
> These errors apply when the resource ID is in the **URL path**.
>
> | Error | Error code | When it applies | How to trigger in UAT |
> | - | - | - | - |
> | [Resource Not Found](https://consumerdatastandardsaustralia.github.io/standards/#error-404-resource-not-found) | `urn:au-cds:error:cds-all:Resource/NotFound` | The URL isn't a CDS endpoint and isn't recognised by the Data Holder | Call a path that doesn't exist, such as `GET /banking/not-an-endpoint` |
> | [Invalid Resource](https://consumerdatastandardsaustralia.github.io/standards/#error-404-resource-invalid) | `urn:au-cds:error:cds-all:Resource/Invalid` | The resource ID is permanently unavailable | Call `GET /banking/payees/{payeeId}` or `GET /banking/accounts/{accountId}/transactions/{transactionId}` with an ID that doesn't exist |
> | [Unavailable Resource](https://consumerdatastandardsaustralia.github.io/standards/#error-404-resource-unavailable) | `urn:au-cds:error:cds-all:Resource/Unavailable` | The resource ID is temporarily unavailable | Requires a resource that your test data marks as temporarily unavailable |
> | [Invalid Banking Account](https://consumerdatastandardsaustralia.github.io/standards/#error-404-authorisation-invalid-banking-account) | `urn:au-cds:error:cds-banking:Authorisation/InvalidBankingAccount` | The bank account is permanently unavailable | Call `GET /banking/accounts/{accountId}` with an account ID that isn't part of the consent |
> | [Unavailable Banking Account](https://consumerdatastandardsaustralia.github.io/standards/#error-404-authorisation-unavailable-banking-account) | `urn:au-cds:error:cds-banking:Authorisation/UnavailableBankingAccount` | The bank account is temporarily unavailable | Requires an account that your test data marks as temporarily unavailable, such as a suspended account |
> | [Invalid Energy Account](https://consumerdatastandardsaustralia.github.io/standards/#error-404-invalid-energy-account) | `urn:au-cds:error:cds-energy:Authorisation/InvalidEnergyAccount` | The energy account is permanently unavailable | Call `GET /energy/accounts/{accountId}` with an account ID that isn't part of the consent |
> | [Unavailable Energy Account](https://consumerdatastandardsaustralia.github.io/standards/#error-404-unavailable-energy-account) | `urn:au-cds:error:cds-energy:Authorisation/UnavailableEnergyAccount` | The energy account is temporarily unavailable | Requires an account that your test data marks as temporarily unavailable |
> | [Invalid Service Point](https://consumerdatastandardsaustralia.github.io/standards/#error-404-invalid-service-point) | `urn:au-cds:error:cds-energy:Authorisation/InvalidServicePoint` | The service point is permanently unavailable | Not testable in UAT, because AEMO data isn't available |
> | [Unavailable Service Point](https://consumerdatastandardsaustralia.github.io/standards/#error-404-unavailable-service-point) | `urn:au-cds:error:cds-energy:Authorisation/UnavailableServicePoint` | The service point is temporarily unavailable | Not testable in UAT, because AEMO data isn't available |

> **406 Not Acceptable**
>
> | Error | Error code | When it applies | How to trigger in UAT |
> | - | - | - | - |
> | [Unsupported Version](https://consumerdatastandardsaustralia.github.io/standards/#error-406-header-unsupported-version) | `urn:au-cds:error:cds-all:Header/UnsupportedVersion` | The requested version is lower than the minimum or higher than the maximum version supported for the endpoint | Pass a positive integer you don't support, such as `x-v=99` |

> **422 Unprocessable Entity**
>
> These errors apply when the resource ID is in the **request body**, plus the arrangement and pagination errors.
>
> | Error | Error code | When it applies | How to trigger in UAT |
> | - | - | - | - |
> | [Invalid Resource](https://consumerdatastandardsaustralia.github.io/standards/#error-422-resource-invalid) | `urn:au-cds:error:cds-all:Resource/Invalid` | A resource ID in the body is permanently unavailable | Send a resource ID that doesn't exist in the body of a `POST` request |
> | [Unavailable Resource](https://consumerdatastandardsaustralia.github.io/standards/#error-422-resource-unavailable) | `urn:au-cds:error:cds-all:Resource/Unavailable` | A resource ID in the body is temporarily unavailable | Requires a resource that your test data marks as temporarily unavailable |
> | [Invalid Banking Account](https://consumerdatastandardsaustralia.github.io/standards/#error-422-authorisation-invalid-banking-account) | `urn:au-cds:error:cds-banking:Authorisation/InvalidBankingAccount` | A bank account ID in the body is permanently unavailable | Call `POST /banking/accounts/balances` with an account ID that isn't part of the consent in `data.accountIds` |
> | [Unavailable Banking Account](https://consumerdatastandardsaustralia.github.io/standards/#error-422-authorisation-unavailable-banking-account) | `urn:au-cds:error:cds-banking:Authorisation/UnavailableBankingAccount` | A bank account ID in the body is temporarily unavailable | Requires an account that your test data marks as temporarily unavailable |
> | [Invalid Energy Account](https://consumerdatastandardsaustralia.github.io/standards/#error-422-invalid-energy-account) | `urn:au-cds:error:cds-energy:Authorisation/InvalidEnergyAccount` | An energy account ID in the body is permanently unavailable | Call `POST /energy/accounts/balances` with an account ID that isn't part of the consent in `data.accountIds` |
> | [Unavailable Energy Account](https://consumerdatastandardsaustralia.github.io/standards/#error-422-unavailable-energy-account) | `urn:au-cds:error:cds-energy:Authorisation/UnavailableEnergyAccount` | An energy account ID in the body is temporarily unavailable | Requires an account that your test data marks as temporarily unavailable |
> | [Invalid Service Point](https://consumerdatastandardsaustralia.github.io/standards/#error-422-invalid-service-point) | `urn:au-cds:error:cds-energy:Authorisation/InvalidServicePoint` | A service point ID in the body is permanently unavailable | Not testable in UAT, because AEMO data isn't available |
> | [Unavailable Service Point](https://consumerdatastandardsaustralia.github.io/standards/#error-422-unavailable-service-point) | `urn:au-cds:error:cds-energy:Authorisation/UnavailableServicePoint` | A service point ID in the body is temporarily unavailable | Not testable in UAT, because AEMO data isn't available |
> | [Invalid Consent Arrangement](https://consumerdatastandardsaustralia.github.io/standards/#error-422-authorisation-invalid-arrangement) | `urn:au-cds:error:cds-all:Authorisation/InvalidArrangement` | The CDR arrangement being revoked was already revoked | Revoke a CDR arrangement that has already been revoked |
> | [Invalid Page](https://consumerdatastandardsaustralia.github.io/standards/#error-422-field-invalid-page) | `urn:au-cds:error:cds-all:Field/InvalidPage` | The requested page is out of range | Pass a page number beyond the last page, such as `page=999` |

> [!TIP]
>
> Test each account and resource error with every [test persona](https://holder.docs.fiskil.dev/api-reference/cdr/testing/test-personas.md). For example, use Persona B's unselected account to confirm that an account the customer owns, but didn't share, is still rejected.

> [!NOTE]
>
> For how your Resource Server should return `403`, `404`, `422`, and `500` errors to Fiskil, see [Errors](https://holder.docs.fiskil.dev/api-reference/cdr/errors.md).

> [!TIP]
>
> When every scenario returns the expected status and error code, continue to [Phase 4: Consent dashboard and revocation](https://holder.docs.fiskil.dev/api-reference/cdr/testing/consent-dashboard.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.