---
name: azion-troubleshoot-cors-policy-errors
description: >-
  Fix a request that the browser blocks under the CORS policy by adding the Access-Control-Allow-Origin header with a Response Phase rule.
---

# Troubleshoot CORS policy errors

This page covers a cross-origin request that the browser blocks under the Cross-Origin Resource Sharing (CORS) policy, when the response comes from an application on Azion. To send CORS headers before an error shows up, refer to [Enable CORS on an application](/en/documentation/guides/application-development/getting-started/cross-origin-resource-sharing-cors/).

---

## A request is blocked with No Access-Control-Allow-Origin header is present

A page on one domain requests a resource on another domain, and the browser blocks the response.

CORS uses HTTP headers to grant a page access to resources on a different origin server. The browser blocks the response because it carries no `Access-Control-Allow-Origin` header for the requesting origin.

The example in this section uses two domains:

- `http://a.domain.com/`, the domain that serves the resource.
- `http://b.domain.com/`, the domain of the page that requests it.

The browser reports the error in this form:

```text
Access to XMLHttpRequest at 'http://a.domain.com/page-cors-subdomain-a.txt' from origin 'http://b.domain.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```

### Confirm the error in the browser

To find the blocked request in Google Chrome:

1. Select **View** > **Developer** > **Developer tools**.
2. Select the **Network** tab.
3. Select the first line, **page-cors-subdomain.a.html**, and read its **Request URL** in the right panel.
4. On the page, select **Test CORS on click**. A red line appears in the **Name** column.
5. Hover over the **page-cors-subdomain-a.txt** line and read the tooltip.
6. Select **page-cors-subdomain-a.txt** and read its details in the right panel.
7. Select the **Console** tab, then **Errors**. The **CORS** error line names the origin domain and the destination domain.

### Add the header with a rule

The fix is a Response Phase rule on the application of domain A. The rule returns the requesting origin in the `Access-Control-Allow-Origin` header when that origin is domain B. For the format a header argument takes, refer to [Rules Engine for Applications](/en/documentation/platform/applications/rules-engine/#add-request-header).

To create the rule in Azion Console:

1. **Open the application**

   Access [Azion Console](https://console.azion.com/) > **Applications**, then select the application of domain A, `a.domain.com`.

2. **Select the Rules Engine tab**

3. **Select + Rule**

4. **Name the rule**

   In the **General** section, enter a **Name**.

5. **Select Response Phase**

   In the **Phase** section, select **Response Phase**.

6. **Set the criterion**

   In the **Criteria** section, select `${http_origin}` as the variable and `is_equal` as the operator, and enter `http://b.domain.com` as the argument. Do not add a trailing slash (`/`).

7. **Add the header behavior**

   In the **Behaviors** section, select *Add Response Header*.

8. **Enter the header**

   Enter `Access-Control-Allow-Origin: ${http_origin}` as the argument.

9. **Select Save**

The rule appears in the **Rules Engine** tab, under **Response**.

### Verify the fix

To test the rule, serve two files from domain A. The page `page-cors-subdomain-a.html` requests the text file when you select its button:

```html
<h2>Using the XMLHttpRequest Object</h2>

<div id="demo">
<button type="button" onclick="loadXMLDoc()">Test CORS on click</button>
</div>

<script>
function loadXMLDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("demo").innerHTML =
      this.responseText;
    }
  };
  xhttp.open("GET", "http://a.domain.com/page-cors-subdomain-a.txt", true);
  xhttp.send();
}
</script>
```

The file `page-cors-subdomain-a.txt` holds the text the page loads:

```text
You clicked!
I belong to the domain a.
Domain b shall call me.
```

To check the result in Google Chrome:

1. Select **View** > **Developer** > **Developer tools**.
2. Select the **Network** tab.
3. Select the first line, **page-cors-subdomain.a.html**, and read its details in the right panel.
4. On the page, select **Test CORS on click**. The page shows `You clicked! I belong to the domain a. Domain b shall call me.`
5. Select the **Console** tab, then **Errors**.

The **Errors** list shows no CORS error, and the response from domain A reaches the page of domain B.

[Chrome browser](https://www.google.com/chrome/) is a registered trademark of Google LLC in the United States and/or other countries.

---

## Related resources

- [Enable CORS on an application](/en/documentation/guides/application-development/getting-started/cross-origin-resource-sharing-cors.md): The rules that send CORS headers for simple requests, complex requests, and a list of allowed origins.
- [Rules Engine for Applications](/en/documentation/platform/applications/rules-engine.md): The phases, variables, operators, and behaviors a rule can use.
- [Create request and response rules](/en/documentation/guides/application-development/getting-started/rules-engine.md): How to add and order rules in each phase of an application.
- [Access Azion Console](/en/documentation/guides/platform/account-and-billing/how-to-access-azion-console.md): How to sign in to the Console where you create the rule.
