---
name: azion-customize-an-error-page
description: >-
  Replace the error responses of a workload with your own pages, one per status code, each with its own cache time and response status code.
---

# Customize an error page

You can replace the error responses of a [workload](/en/documentation/platform/workloads/) with pages of your own, for several status codes at once, from Azion Console, the [Azion CLI](/en/documentation/devtools/cli/), or the API. To create your first set with one page and see it replace a `404`, refer to [Custom Pages quickstart](/en/documentation/platform/workloads/custom-pages/quickstart/).

With [Custom Pages](/en/documentation/platform/workloads/#custom-pages), the pages live in a custom page set. Each page answers one status code that the application's [connector](/en/documentation/platform/connectors/) returns, and the set serves pages only after the workload's deployment names it.

An application that runs on API v3 sets its error pages in Error Responses instead. For more information, refer to [Error Responses](/en/documentation/platform/workloads/custom-pages/error-responses/).

---

Select an interface. The prerequisites and the steps of each task follow your choice.

## Prerequisites

- A workload and an application for it to serve. To create both, refer to [Workloads quickstart](/en/documentation/platform/workloads/quickstart/).
- A connector that serves your error page documents, each at its own path. For more information, refer to [Connectors](/en/documentation/platform/connectors/).

**Console**

- Access to Azion Console. For more information, refer to [How to access Azion Console](/en/documentation/guides/platform/account-and-billing/how-to-access-azion-console/).
- A workload whose deployment names the application.

**CLI**

- The [Azion CLI](/en/documentation/devtools/cli/), authorized with your account. This page matches Azion CLI 4.23.0.
- A workload with no deployment yet. The CLI sets the custom page set of a workload only when it creates the deployment, and a workload holds one deployment. This guide creates the deployment.
- The workload ID, the ID of the application the workload serves, and the connector ID.

**API**

- A personal token for the `Authorization` header, in the form `Token [TOKEN VALUE]`. To create a token, refer to [Personal tokens](/en/documentation/fundamentals/personal-tokens/).
- `curl` or another HTTP client.
- A workload whose deployment names the application.
- The workload ID, the ID of the application the workload serves, and the connector ID.
- The deployment ID. `azion list workload-deployment --workload-id <workload-id>` prints it in the `ID` column.

---

## Create a set with a page for each code

Each page in the set takes its own status code, connector path, cache time, and response status code. A page can also answer with a code other than the one the connector returned, such as a `404` in place of a `403`. Azion serves the page in place, with no redirect. After you change a page's document, Azion keeps serving the cached copy until its cache time runs out. For the codes a page accepts and the range of each field, refer to [Custom page settings](/en/documentation/platform/workloads/custom-pages/settings/#page-fields).

**Console**

To create the set in Azion Console:

1. **Open the Custom Pages page**

   Access [Azion Console](https://console.azion.com/) > **Custom Pages**.

2. **Start the set**

   Select **Create Custom Page**. To add pages to a set you already have, select that set instead.

3. **Name the set**

   In **Name**, enter a name that identifies the set, such as `my-error-pages`.

4. **Select Create Custom Page Code**

5. **Select the status code**

   In **Page Code**, select the status code your connector returns, such as `404`.

6. **Select the connector**

   In **Connector**, select the connector that holds the page.

7. **Enter the page path**

   In **Page Path (URI)**, enter the path of the page on the connector, such as `/errors/404.html`.

8. **Set the cache time**

   In **Response TTL**, enter the number of seconds the page stays in cache, such as `3600`.

9. **(Optional) Set the response status code**

   In **Response Custom Status Code**, enter the status code the client receives instead of the original one.

10. **Add the other codes**

    Select **Create Custom Page Code** again for each other status code, and fill in its fields the same way.

11. **Save the set**

    Select **Create**. On a set you already have, select **Save**.

The **Page Codes** table lists one row per page, with its **Page Status Code**, **Page Path (URI)**, **Custom Status Code**, and **Response TTL**.

**CLI**

To create the set with the Azion CLI, save a JSON file with one entry in `pages` per status code, here as `pages.json`. This set answers a `404` with the page at `/errors/404.html`, and answers a `403` with the same page and status `404`:

```json
{"name": "my-error-pages", "active": true, "pages": [
  {"code": "404", "page": {"type": "page_connector", "attributes": {"connector": <connector-id>, "ttl": 3600, "uri": "/errors/404.html", "custom_status_code": 404}}},
  {"code": "403", "page": {"type": "page_connector", "attributes": {"connector": <connector-id>, "ttl": 3600, "uri": "/errors/404.html", "custom_status_code": 404}}}
]}
```

Create the set from the file:

```bash
azion create custom-pages --file pages.json
```

The command prints the ID of the new set. The deployment needs it in the next task:

```text
Created Custom Page with ID <custom-page-id>
```

A file whose `pages` list is empty is refused with `Ensure this field has at least 1 elements.`

**API**

To create the set with the API, send a `POST` request to the custom pages endpoint, with one entry in `pages` per status code. This set answers a `404` with the page at `/errors/404.html`, and answers a `403` with the same page and status `404`:

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/custom_pages \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "my-error-pages",
  "active": true,
  "pages": [
    {"code": "404", "page": {"type": "page_connector", "attributes": {"connector": <connector-id>, "ttl": 3600, "uri": "/errors/404.html", "custom_status_code": 404}}},
    {"code": "403", "page": {"type": "page_connector", "attributes": {"connector": <connector-id>, "ttl": 3600, "uri": "/errors/404.html", "custom_status_code": 404}}}
  ]
}'
```

The API answers `201` with the new set, its `id` included. A `GET` request to `/v4/workspace/custom_pages` lists your sets with their IDs. A body whose `pages` list is empty is refused with `Ensure this field has at least 1 elements.`

---

## Assign the set in the workload's deployment

The deployment of a workload names its application, its firewall, and its custom page set. Only the custom page set changes here, so the application and the firewall keep the values the workload uses today.

**Console**

To assign the set in Azion Console:

1. **Open the Workloads page**

   Access [Azion Console](https://console.azion.com/) > **Workloads**.

2. **Open the workload**

   Select the workload whose error responses the set replaces. Its edit form opens.

3. **Select your set**

   In the **Deployment Settings** section, select your set in the **Custom Page** field. In a workload with no set, the field reads *Select a custom page*.

   **Application** and **Firewall** keep the values the workload serves today.

4. **Save the workload**

   Select **Save**.

Azion Console shows "Your workload has been updated", and the deployment of the workload names your set.

**CLI**

To assign the set with the Azion CLI, create the workload's deployment with the set in `--custom-page`:

```bash
azion create workload-deployment \
  --workload-id <workload-id> \
  --name my-deployment \
  --application-id <application-id> \
  --custom-page <custom-page-id> \
  --strategy-type default \
  --active true \
  --current true
```

The command prints the ID of the new deployment:

```text
Created Workload Deployment with ID <deployment-id>
```

If the workload uses a firewall, add `--firewall-id <firewall-id>` to the command. On a workload that already has a deployment, the command fails with `The maximum number of deployments allowed per workload is 1.` Azion CLI 4.23.0 has no command that changes a deployment, so assign the set to that workload in Azion Console or with the API.

**API**

To assign the set with the API, send a `PATCH` request to the deployment of the workload. The set goes in `strategy.attributes.custom_page`, beside the application the deployment names today. Leave out `firewall` if the deployment has no firewall:

```bash
curl --request PATCH \
  --url https://api.azion.com/v4/workspace/workloads/<workload-id>/deployments/<deployment-id> \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "strategy": {
    "type": "default",
    "attributes": {
      "application": <application-id>,
      "firewall": <firewall-id>,
      "custom_page": <custom-page-id>
    }
  }
}'
```

The API answers `202`. The deployment then names your set in `custom_page`.

---

## Confirm that a page replaces the error

The check is the same for every interface. A change to a workload's deployment takes several minutes to reach all of Azion's distributed infrastructure, and requests can receive the previous or the updated configuration meanwhile. Repeat a request until the answers agree.

Request a path for which your connector returns a status code the set covers. Replace `<your-domain>` with a domain the workload serves, such as its workload domain of the form `<id>.map.azionedge.net`:

```bash
curl -s -D - https://<your-domain>/<missing-path>
```

For a page whose response status code is `404`, the response starts with this status line, followed by the headers your connector sends and the document at the page's path:

```text
HTTP/2 404 
```

The response carries no `Location` header, so the client stays on the requested URL and is not redirected. If the connector's own error response still arrives after the deployment change has spread, refer to [Troubleshoot Workloads](/en/documentation/platform/workloads/troubleshooting/#custom-pages).

---

## Next steps

- [Custom page settings](/en/documentation/platform/workloads/custom-pages/settings.md): Look up every status code a page accepts, the range of each field, and the API errors.
- [How Workloads works](/en/documentation/platform/workloads/how-it-works.md#custom-pages): Follow a response from the connector's status code to the page the client receives.
- [Workload settings](/en/documentation/platform/workloads/settings.md#deployment): Check every field of the deployment that names the application, firewall, and custom page set.
- [Troubleshoot Workloads](/en/documentation/platform/workloads/troubleshooting.md#custom-pages): Find why a workload still returns the connector's error response instead of your page.
