---
title: Cloudflare Rules
description: Use Cloudflare Rules to adjust requests and responses, configure settings, and trigger actions for specific requests.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cloudflare Rules

 Available on all plans 

Cloudflare Rules allows you to make adjustments to requests and responses, configure Cloudflare settings, and trigger specific actions for matching requests.

Rules features require that you [proxy the DNS records](https://developers.cloudflare.com/dns/proxy-status/) of your domain (or subdomain) through Cloudflare.

---

## Features

### Configuration Rules

Customize Cloudflare configuration settings for matching incoming requests.

[ Use Configuration Rules ](https://developers.cloudflare.com/rules/configuration-rules/) 

### Snippets

Customize the behavior of your website or application using short pieces of JavaScript code.

[ Use Snippets ](https://developers.cloudflare.com/rules/snippets/) 

### Transform Rules

Adjust the URI path, query string, and HTTP headers of requests and responses on the Cloudflare global network.

[ Use Transform Rules ](https://developers.cloudflare.com/rules/transform/) 

### Redirects

Redirect visitors from a source URL to a target URL with a specific HTTP status code. Use Single Redirects or Bulk Redirects depending on your use case.

[ Use Redirects ](https://developers.cloudflare.com/rules/url-forwarding/) 

### Origin Rules

Customize where the incoming traffic will go and with which parameters. Override request properties such as `Host` header, destination hostname, and destination port.

[ Use Origin Rules ](https://developers.cloudflare.com/rules/origin-rules/) 

### Cloud Connector

Route matching incoming traffic from your website to a public cloud provider such as AWS, Google Cloud, and Azure.

[ Use Cloud Connector ](https://developers.cloudflare.com/rules/cloud-connector/) 

### Compression Rules

Customize the compression applied to responses from Cloudflare's global network to your website visitors, based on the file extension and content type.

[ Use Compression Rules ](https://developers.cloudflare.com/rules/compression-rules/) 

### Page Rules

Trigger certain actions when a request matches a URL pattern.

[ Use Page Rules ](https://developers.cloudflare.com/rules/page-rules/) 

### URL normalization

Modify the URLs of incoming requests so that they conform to a consistent formatting standard.

[ Configure URL normalization ](https://developers.cloudflare.com/rules/normalization/) 

### Custom Errors

Define what custom content to serve for errors returned by an origin server or by a Cloudflare product, including Workers.

[ Configure Custom Errors ](https://developers.cloudflare.com/rules/custom-errors/) 

---

## Related products

**[Custom rules](https://developers.cloudflare.com/waf/custom-rules/)** 

Control incoming traffic by filtering requests to a zone. You can block or challenge incoming requests according to rules you define.

**[Rate limiting rules](https://developers.cloudflare.com/waf/rate-limiting-rules/)** 

Define rate limits for requests matching an expression, and the action to perform when those rate limits are reached.

**[Cache rules](https://developers.cloudflare.com/cache/how-to/cache-rules/)** 

Customize the cache properties of your HTTP requests.

**[Workers](https://developers.cloudflare.com/workers/)** 

Cloudflare Workers provides a serverless execution environment that allows you to create new applications or augment existing ones without configuring or maintaining infrastructure.

---

## More resources

[Plans](https://www.cloudflare.com/plans/#overview) 

Compare available Cloudflare plans

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}}]}
```

---

---
title: Rules examples
description: Explore the following examples for Rules.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/examples.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Rules examples

Explore the following examples for Rules.

Note

We have a separate listing for [Cache rules examples](https://developers.cloudflare.com/cache/how-to/cache-rules/examples/).

Filter resources...

[Route /images to an S3 Bucket using TerraformRoute requests with a URI path starting with /images to a specific AWS S3 bucket with Cloud Connector using Terraform.](https://developers.cloudflare.com/rules/cloud-connector/examples/route-images-to-aws-s3-using-terraform/)[Route /images to an S3 BucketRoute requests with a URI path starting with /images to a specific AWS S3 bucket using Cloud Connector.](https://developers.cloudflare.com/rules/cloud-connector/examples/route-images-to-s3/)[Send EU visitors to a Google Cloud Storage bucketRoute all traffic from EU visitors to a Google Cloud Storage bucket using Cloud Connector.](https://developers.cloudflare.com/rules/cloud-connector/examples/send-eu-visitors-to-gcs/)[Serve /static-assets from Azure Blob StorageRoute requests with a URI path starting with /static-assets to an Azure Blob Storage container using Cloud Connector.](https://developers.cloudflare.com/rules/cloud-connector/examples/serve-static-assets-from-azure/)[Disable Brotli compressionCreate a compression rule to turn off Brotli compression for all incoming requests of a given zone.](https://developers.cloudflare.com/rules/compression-rules/examples/disable-all-brotli/)[Disable compression for AVIF imagesCreate a compression rule to turn off compression for AVIF images, based on either the content type or the file extension specified in the request.](https://developers.cloudflare.com/rules/compression-rules/examples/disable-compression-avif/)[Enable Zstandard compression for default content typesCreate a compression rule to turn on Zstandard compression for response content types where Cloudflare applies compression by default.](https://developers.cloudflare.com/rules/compression-rules/examples/enable-zstandard/)[Use Gzip compression for CSV filesCreate a compression rule to set Gzip compression as the preferred compression method for CSV files.](https://developers.cloudflare.com/rules/compression-rules/examples/gzip-for-csv/)[Use only Brotli compression for a specific pathCreate a compression rule to set Brotli as the only supported compression algorithm for a specific URI path.](https://developers.cloudflare.com/rules/compression-rules/examples/only-brotli-url-path/)[Define a single configuration rule using TerraformCreate a configuration rule using Terraform to turn off Email Obfuscation and Browser Integrity Check for API requests in a given zone.](https://developers.cloudflare.com/rules/configuration-rules/examples/define-single-configuration-terraform/)[Change the HTTP Host header and DNS recordCreate an origin rule to change the HTTP Host header and the resolved DNS record.](https://developers.cloudflare.com/rules/origin-rules/examples/change-http-host-header/)[Change the destination portCreate an origin rule to change the destination port.](https://developers.cloudflare.com/rules/origin-rules/examples/change-port/)[Define a single origin rule using TerraformCreate an origin rule using Terraform to override the Host header, the resolved hostname, and the destination port of API requests.](https://developers.cloudflare.com/rules/origin-rules/examples/define-single-origin-terraform/)[A/B testing with same-URL direct accessSet up an A/B test by controlling what response is served based on cookies.](https://developers.cloudflare.com/rules/snippets/examples/ab-testing-same-url/)[Append dates to cookies to use with A/B testingDynamically set a cookie expiration and test group.](https://developers.cloudflare.com/rules/snippets/examples/append-dates-to-cookies/)[Auth with headersAllow or deny a request based on a known pre-shared key in a header. This is not meant to replace the WebCrypto API.](https://developers.cloudflare.com/rules/snippets/examples/auth-with-headers/)[Send Bot Management information to originSend Bots information to your origin. Refer to Bot Management variables for a full list of available fields.](https://developers.cloudflare.com/rules/snippets/examples/bot-data-to-origin/)[Send suspect bots to a honeypotUse the bot score field to send bots to a honeypot.](https://developers.cloudflare.com/rules/snippets/examples/bots-to-honeypot/)[Bulk redirect based on a map objectRedirect requests to certain URLs based on a mapped object to the request's URL.](https://developers.cloudflare.com/rules/snippets/examples/bulk-redirect-map/)[Country code redirectRedirect a response based on the country code in the header of a visitor.](https://developers.cloudflare.com/rules/snippets/examples/country-code-redirect/)[Custom cacheStore, retrieve, and remove assets from cache programmatically. Use this template to optimize performance and implement custom caching strategies.](https://developers.cloudflare.com/rules/snippets/examples/custom-cache/)[Debugging logsSend debugging information in an errored response to a logging service.](https://developers.cloudflare.com/rules/snippets/examples/debugging-logs/)[Define CORS headersAdjust Cross-Origin Resource Sharing (CORS) headers and handle preflight requests.](https://developers.cloudflare.com/rules/snippets/examples/define-cors-headers/)[Follow redirects from the originModify the fetch request to follow redirects from the origin, ensuring the client receives the final response.](https://developers.cloudflare.com/rules/snippets/examples/follow-redirects/)[Add HEX timestamp to a request headerAdd a custom header to requests sent to the origin server with the current timestamp in hexadecimal format for debugging, tracking, or custom routing purposes.](https://developers.cloudflare.com/rules/snippets/examples/hex-timestamp/)[Validate JSON web tokens (JWT)Extract the JWT token from a header, decode it, and implement validation checks to verify it.](https://developers.cloudflare.com/rules/snippets/examples/jwt-validation/)[Maintenance pageServe a custom maintenance page instead of fetching content from the origin server or cache. Ideal for downtime notifications, planned maintenance, or emergency messages.](https://developers.cloudflare.com/rules/snippets/examples/maintenance/)[Override a Set-Cookie header with a certain valueGet a specific Set-Cookie header and update it with a certain value.](https://developers.cloudflare.com/rules/snippets/examples/override-set-cookies-value/)[Redirect 403 Forbidden to a different pageIf origin responded with 403 Forbidden error code, redirect to different page.](https://developers.cloudflare.com/rules/snippets/examples/redirect-forbidden-status/)[Redirect from one domain to anotherRedirect all requests from one domain to another domain.](https://developers.cloudflare.com/rules/snippets/examples/redirect-replaced-domain/)[Remove fields from API responseIf origin responds with JSON, parse the response and delete fields to return a modified response.](https://developers.cloudflare.com/rules/snippets/examples/remove-fields-api-response/)[Remove query strings before sending request to originRemove certain query strings from a request before passing to the origin.](https://developers.cloudflare.com/rules/snippets/examples/remove-query-strings/)[Remove response headersRemove from response all headers that start with a certain name.](https://developers.cloudflare.com/rules/snippets/examples/remove-response-headers/)[Return information about the incoming requestRespond with information about the incoming request provided by Cloudflare’s global network.](https://developers.cloudflare.com/rules/snippets/examples/return-incoming-request-properties/)[Rewrite links on HTML pagesDynamically rewrite links in HTML responses. This is useful for site migrations and branding updates.](https://developers.cloudflare.com/rules/snippets/examples/rewrite-site-links/)[Change origin and modify pathsRoute requests to a different origin, prepend a directory to the URL path, and remove specific segments.](https://developers.cloudflare.com/rules/snippets/examples/route-and-rewrite/)[Set security headersSet common security headers such as X-XSS-Protection, X-Frame-Options, and X-Content-Type-Options.](https://developers.cloudflare.com/rules/snippets/examples/security-headers/)[Send timestamp to origin as a custom headerConvert timestamp to hexadecimal format and send it as a custom header to the origin.](https://developers.cloudflare.com/rules/snippets/examples/send-timestamp-to-origin/)[Route to a different origin based on origin responseIf response to the original request is not 200 OK or a redirect, send to another origin.](https://developers.cloudflare.com/rules/snippets/examples/serve-different-origin/)[Sign requestsVerify a signed request using the HMAC and SHA-256 algorithms or return a 403.](https://developers.cloudflare.com/rules/snippets/examples/signing-requests/)[Slow down suspicious requestsDefine a delay to be used when incoming requests match a rule you consider suspicious based on the bot score.](https://developers.cloudflare.com/rules/snippets/examples/slow-suspicious-requests/)[Add a wildcard CORS response headerCreate a CORS response header transform rule to add an Access-Control-Allow-Origin HTTP header to the response with wildcard as static value. (cookiename=value).](https://developers.cloudflare.com/rules/transform/examples/add-cors-header/)[Add a request header with the current bot scoreCreate a request header transform rule to add a X-Bot-Score HTTP header to the request with the current bot score.](https://developers.cloudflare.com/rules/transform/examples/add-request-header-bot-score/)[Add request header with a static valueCreate a request header transform rule to add an X-Source HTTP header to the request with a static value (Cloudflare).](https://developers.cloudflare.com/rules/transform/examples/add-request-header-static-value/)[Add a request header for subrequests from other zonesCreate a request header transform rule to add an HTTP header when the Workers subrequest comes from a different zone.](https://developers.cloudflare.com/rules/transform/examples/add-request-header-subrequest-other-zone/)[Add a response header with a static valueCreate a response header transform rule to add a set-cookie HTTP header to the response with a static value (cookiename=value).](https://developers.cloudflare.com/rules/transform/examples/add-response-header-static-value/)[Normalize encoded slashes in URL pathCreate a URL rewrite rule (part of Transform Rules) to normalize encoded forward slashes (%2F) in the request path to standard slashes (/).](https://developers.cloudflare.com/rules/transform/examples/normalize-encoded-slash/)[Remove a request headerCreate a request header transform rule (part of Transform Rules) to remove the cf-connecting-ip HTTP header from the request.](https://developers.cloudflare.com/rules/transform/examples/remove-request-header/)[Remove a response headerCreate a response header transform rule (part of Transform Rules) to remove the cf-connecting-ip HTTP header from the response.](https://developers.cloudflare.com/rules/transform/examples/remove-response-header/)[Rewrite blog archive URLsCreate a transform rule to rewrite the URL format /posts/<YYYY>-<MM>-<DD>-<TITLE> to the new format /posts/<YYYY>/<MM>/<DD>/<TITLE>.](https://developers.cloudflare.com/rules/transform/examples/rewrite-archive-urls-new-format/)[Rewrite path of moved section of a websiteCreate a URL rewrite rule (part of Transform Rules) to rewrite everything under /blog/<PATH> to /marketing/<PATH>.](https://developers.cloudflare.com/rules/transform/examples/rewrite-moved-section/)[Rewrite path of archived blog postsCreate a URL rewrite rule (part of Transform Rules) to rewrite any requests for /news/2012/... URI paths to /archive/news/2012/....](https://developers.cloudflare.com/rules/transform/examples/rewrite-path-archived-posts/)[Rewrite path for object storage bucketCreate a URL rewrite rule (part of Transform Rules) to rewrite any requests for /files/... URI paths to /....](https://developers.cloudflare.com/rules/transform/examples/rewrite-path-object-storage/)[Rewrite image paths with several URL segmentsCreate a URL rewrite rule (part of Transform Rules) to rewrite any requests for /images/<FOLDER1>/<FOLDER2>/<FILENAME> to /img/<FILENAME>.](https://developers.cloudflare.com/rules/transform/examples/rewrite-several-url-different-url/)[Rewrite URL query stringCreate a transform rule to rewrite the request path from /blog to /blog?sort-by=date.](https://developers.cloudflare.com/rules/transform/examples/rewrite-url-string-visitors/)[Rewrite page path for visitors in specific countriesCreate two URL rewrite rules (part of Transform Rules) to rewrite the path of the welcome page for visitors in specific countries.](https://developers.cloudflare.com/rules/transform/examples/rewrite-welcome-for-countries/)[Set a response header with the current bot scoreCreate a response header transform rule (part of Transform Rules) to set an X-Bot-Score HTTP header in the response with the current bot score.](https://developers.cloudflare.com/rules/transform/examples/set-response-header-bot-score/)[Set response header with a static valueCreate a response header transform rule (part of Transform Rules) to set an X-Bot-Score HTTP header in the response to a static value (Cloudflare).](https://developers.cloudflare.com/rules/transform/examples/set-response-header-static-value/)[Perform mobile redirectsCreate a redirect rule to redirect visitors using mobile devices to a different hostname.](https://developers.cloudflare.com/rules/url-forwarding/examples/perform-mobile-redirects/)[Redirect admin area requests to HTTPSCreate a redirect rule to redirect requests for the administration area of store.example.com to HTTPS, keeping the original path and query string.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-admin-https/)[Redirect requests from one domain to anotherCreate a redirect rule to redirect all requests to a different domain, maintaining all functionality, except for the discontinued HTTP service (port 80).](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-all-another-domain/)[Redirect requests from one country to a domainCreate a redirect rule to redirect all website visitors from the United Kingdom to a different domain, maintaining the current functionality in the same paths.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-all-country/)[Redirect requests for a domain to a new domainCreate a redirect rule to redirect all URLs for a domain to point to the root of a new domain, including any subdomains of the old domain.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-all-different-domain-root/)[Redirect requests to a different hostnameCreate a redirect rule to redirect all requests for smallshop.example.com to a different hostname using HTTPS, keeping the original path and query string.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-all-different-hostname/)[Redirect local visitors to specific subdomainsCreate a redirect rule to redirect United Kingdom and France visitors from the example.com website's root path (/) to their localized subdomains https://gb.example.com and https://fr.example.com, respectively.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-country-subdomains/)[Redirect visitors to a new page URLCreate a redirect rule to redirect visitors from /contact-us/ to the page's new path /contacts/.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-new-url/)[Redirect from root to WWWCreate a redirect rule to forward HTTPS requests from the root (also known as the “apex” or “naked” domain) to the WWW subdomain.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-root-to-www/)[Redirect from WWW to rootCreate a redirect rule to forward HTTPS requests from the WWW subdomain to the root (also known as the “apex” or “naked” domain).](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-www-to-root/)[Remove locale from URL pathCreate a redirect rule to redirect visitors from an old URL format with locale information to a new URL format.](https://developers.cloudflare.com/rules/url-forwarding/examples/remove-locale-url/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/examples/","name":"Rules examples"}}]}
```

---

---
title: Configuration Rules
description: Configuration Rules allow you to customize certain Cloudflare configuration settings for matching incoming requests.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/configuration-rules/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Configuration Rules

Configuration Rules allow you to customize certain Cloudflare [configuration settings](https://developers.cloudflare.com/rules/configuration-rules/settings/) for matching incoming requests.

The configuration rule expression will determine to which requests the rule settings will apply. For more information on expressions, refer to [Expressions](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/) and [Edit expressions in the dashboard](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/).

Note

Configuration Rules require that you [proxy the DNS records](https://developers.cloudflare.com/dns/proxy-status/) of your domain (or subdomain) through Cloudflare.

---

## Rules templates

Cloudflare provides you with rules templates for common use cases.

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Templates**, and then select one of the available templates.

You can also refer to the [Examples gallery](https://developers.cloudflare.com/rules/examples/) in the developer docs.

## Availability

The number of available configuration rules varies according to your Cloudflare plan:

| Free            | Pro | Business | Enterprise |     |
| --------------- | --- | -------- | ---------- | --- |
| Availability    | Yes | Yes      | Yes        | Yes |
| Number of rules | 10  | 25       | 50         | 300 |

## Execution order

The execution order of Rules features is the following:

* [Single Redirects](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/)
* [URL Rewrite Rules](https://developers.cloudflare.com/rules/transform/url-rewrite/)
* [Configuration Rules](https://developers.cloudflare.com/rules/configuration-rules/)
* [Origin Rules](https://developers.cloudflare.com/rules/origin-rules/)
* [Bulk Redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/)
* [Managed Transforms](https://developers.cloudflare.com/rules/transform/managed-transforms/)
* [Request Header Transform Rules](https://developers.cloudflare.com/rules/transform/request-header-modification/)
* [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/)
* [Snippets](https://developers.cloudflare.com/rules/snippets/)
* [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/)

The different types of rules listed above will take precedence over [Page Rules](https://developers.cloudflare.com/rules/page-rules/). This means that Page Rules will be overridden if there is a match for both Page Rules and the Rules products listed above.

Generally speaking, for [non-terminating actions](https://developers.cloudflare.com/ruleset-engine/rules-language/actions/) the last change made by rules in the same [phase](https://developers.cloudflare.com/ruleset-engine/about/phases/) will win (later rules can overwrite changes done by previous rules). However, for terminating actions (_Block_, _Redirect_, or one of the challenge actions), rule evaluation will stop and the action will be executed immediately.

For example, if multiple rules with the _Redirect_ action match, Cloudflare will always use the URL redirect of the first rule that matches. Also, if you configure URL redirects using different Cloudflare products (Single Redirects and Bulk Redirects), the product executed first will apply, if there is a rule match (in this case, Single Redirects).

Refer to the [Phases list](https://developers.cloudflare.com/ruleset-engine/reference/phases-list/) for the product execution order.

Warning

Using Cloudflare challenges along with Rules features may cause challenge loops. Refer to [Rules troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/) for more information.

## Troubleshooting

When troubleshooting Configuration Rules, use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to determine if a rule is triggering for a specific URL.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/configuration-rules/","name":"Configuration Rules"}}]}
```

---

---
title: Create a configuration rule via API
description: Use the Rulesets API to create configuration rules via API.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/configuration-rules/create-api.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a configuration rule via API

Use the [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/) to create configuration rules via API.

## Basic rule settings

When creating a configuration rule via API, make sure you:

* Set the rule action to `set_config`.
* Define the parameters in the `action_parameters` field according to the [settings](https://developers.cloudflare.com/rules/configuration-rules/settings/) you wish to override for matching requests.
* Deploy the rule to the `http_config_settings` phase at the zone level.

## Procedure

Follow this workflow to create a configuration rule for a given zone via API:

1. Use the [List zone rulesets](https://developers.cloudflare.com/api/resources/rulesets/methods/list/) operation to check if there is already a ruleset for the `http_config_settings` phase at the zone level.
2. If the phase ruleset does not exist, create it using the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) operation. In the new ruleset properties, set the following values:  
   * **kind**: `zone`  
   * **phase**: `http_config_settings`
3. Use the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation to add a configuration rule to the list of ruleset rules. Alternatively, include the rule in the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) request mentioned in the previous step.

Make sure your API token has the [required permissions](#required-api-token-permissions) to perform the API operations.

## Example requests

Example: Add a rule that enables Email Obfuscation and Browser Integrity Check

The following example sets the rules of an existing phase ruleset (`{ruleset_id}`) to a single configuration rule — enabling Email Obfuscation and Browser Integrity Check for the contacts page — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "enable_email_obfuscation_bic",

            "expression": "starts_with(http.request.uri.path, \"/contact-us/\")",

            "description": "Obfuscates email addresses and enables BIC in contacts page",

            "action": "set_config",

            "action_parameters": {

                "email_obfuscation": true,

                "bic": true

            }

        }

    ]

  }'


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

Example: Add a rule that turns on Under Attack mode for the admin area

The following example sets the rules of an existing phase ruleset (`{ruleset_id}`) to a single configuration rule — turning on Under Attack mode for the administration area — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "enable_under_attack_in_admin",

            "expression": "http.host eq \"admin.example.com\"",

            "description": "Turn on Under Attack mode for admin area",

            "action": "set_config",

            "action_parameters": {

                "security_level": "under_attack"

            }

        }

    ]

  }'


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

---

## Required API token permissions

The API token used in API requests to manage configuration rules must have at least the following permission:

* _Zone_ \> _Config Rules_ \> _Edit_

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/configuration-rules/","name":"Configuration Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/configuration-rules/create-api/","name":"Create a configuration rule via API"}}]}
```

---

---
title: Create a configuration rule in the dashboard
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/configuration-rules/create-dashboard.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a configuration rule in the dashboard

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Create rule** \> **Configuration Rule**.
3. (Optional) Select one of the rule templates that address common use cases. Then, review and adjust the proposed rule configuration.
4. Enter a descriptive name for the rule in **Rule name**.
5. Under **When incoming requests match**, select if you wish to apply the rule to all incoming requests or only to requests that match a custom filter expression.
6. (Optional) To define a custom expression, use the Expression Builder (specifying one or more values for **Field**, **Operator**, and **Value**) or manually enter an expression using the Expression Editor. For more information, refer to [Edit expressions in the dashboard](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/).
7. Under **Then the settings are**, add the [configuration settings](https://developers.cloudflare.com/rules/configuration-rules/settings/) you wish to change for requests matching the rule expression.
8. To save and deploy your rule, select **Deploy**. If you are not ready to deploy your rule, select **Save as Draft**.  
If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to [Troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/#this-rule-may-not-apply-to-your-traffic) for more information.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/configuration-rules/","name":"Configuration Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/configuration-rules/create-dashboard/","name":"Create a configuration rule in the dashboard"}}]}
```

---

---
title: Configuration Rules examples
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/configuration-rules/examples/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Configuration Rules examples

[Define a single configuration rule using TerraformCreate a configuration rule using Terraform to turn off Email Obfuscation and Browser Integrity Check for API requests in a given zone.](https://developers.cloudflare.com/rules/configuration-rules/examples/define-single-configuration-terraform/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/configuration-rules/","name":"Configuration Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/configuration-rules/examples/","name":"Configuration Rules examples"}}]}
```

---

---
title: Define a single configuration rule using Terraform
description: Create a configuration rule using Terraform to turn off Email Obfuscation and Browser Integrity Check for API requests in a given zone.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/configuration-rules/examples/define-single-configuration-terraform.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Define a single configuration rule using Terraform

Create a configuration rule using Terraform to turn off Email Obfuscation and Browser Integrity Check for API requests in a given zone.

Note

Terraform code snippets below refer to the v4 SDK only.

The following example defines a single configuration rule for a zone using Terraform. The rule disables Email Obfuscation and Browser Integrity Check for API requests.

```

# Disable a couple of Cloudflare settings for API requests

resource "cloudflare_ruleset" "http_config_rules_example" {

  zone_id     = "<ZONE_ID>"

  name        = "Config rules ruleset"

  description = "Set configuration rules for incoming requests"

  kind        = "zone"

  phase       = "http_config_settings"


  rules {

    ref         = "disable_obfuscation_bic"

    description = "Disable email obfuscation and BIC for API requests"

    expression  = "(http.request.uri.path matches \"^/api/\")"

    action      = "set_config"

    action_parameters {

      email_obfuscation = false

      bic               = false

    }

  }

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

## Additional resources

For additional guidance on using Terraform with Cloudflare, refer to the following resources:

* [Terraform documentation](https://developers.cloudflare.com/terraform/)
* [Cloudflare Provider for Terraform ↗](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs) (reference documentation)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/configuration-rules/","name":"Configuration Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/configuration-rules/examples/","name":"Configuration Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/configuration-rules/examples/define-single-configuration-terraform/","name":"Define a single configuration rule using Terraform"}}]}
```

---

---
title: Configuration Rules settings
description: You can change the configuration settings described below in a configuration rule.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/configuration-rules/settings.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Configuration Rules settings

You can change the configuration settings described below in a configuration rule.

## Automatic HTTPS Rewrites

[Automatic HTTPS Rewrites](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/automatic-https-rewrites/) prevents end users from seeing `Mixed content` errors by rewriting URLs from `http` to `https` for resources or links on your website that can be served with HTTPS.

Use this setting to turn on or off Automatic HTTPS Rewrites for matching requests.

API information

API configuration property name: `"automatic_https_rewrites"` (boolean).

API configuration example

```

"action_parameters": {

  "automatic_https_rewrites": true

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## Browser Integrity Check

[Browser Integrity Check](https://developers.cloudflare.com/waf/tools/browser-integrity-check/) blocks access to pages based on specific HTTP headers commonly abused by spammers.

Use this setting to turn on or off Browser Integrity Check for matching requests.

API information

API configuration property name: `"bic"` (boolean).

API configuration example

```

"action_parameters": {

  "bic": true

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## Disable Real User Monitoring (RUM)

[Cloudflare Web Analytics](https://developers.cloudflare.com/web-analytics/), also known as Real User Monitoring (RUM), is Cloudflare's free, privacy-first analytics for your website.

Use this setting to turn off Web Analytics for matching requests.

Warning

Configuration rules have precedence over any Web Analytics rules. If a Web Analytics rule turns on analytics measurements for an incoming request and the same request matches a configuration rule turning off Web Analytics, the configuration rule will win.

API information

API configuration property name: `"disable_rum"` (boolean).

API configuration example

```

"action_parameters": {

  "disable_rum": true

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## Disable Zaraz

[Cloudflare Zaraz](https://developers.cloudflare.com/zaraz/) gives you complete control over third-party tools and services for your website, and allows you to offload them to the Cloudflare global network.

Use this setting to turn off Zaraz for matching requests.

API information

API configuration property name: `"disable_zaraz"` (boolean).

API configuration example

```

"action_parameters": {

  "disable_zaraz": true

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## Email Obfuscation

[Email Obfuscation](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/) prevents spam by hiding email addresses from bots and harvesters while keeping them visible to human visitors to your site.

Use this setting to turn on or off Email Obfuscation for matching requests.

API information

API configuration property name: `"email_obfuscation"` (boolean).

API configuration example

```

"action_parameters": {

  "email_obfuscation": false

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## Fonts

[Cloudflare Fonts](https://developers.cloudflare.com/speed/optimization/content/fonts/) rewrites Google Fonts to be delivered from a website's own origin, eliminating the need to rely on third-party font providers.

Use this setting to turn on or off Cloudflare Fonts for matching requests.

API information

API configuration property name: `"fonts"` (boolean).

API configuration example

```

"action_parameters": {

  "fonts": false

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## Hotlink Protection

[Hotlink Protection](https://developers.cloudflare.com/waf/tools/scrape-shield/hotlink-protection/) prevents your images from being used by other sites, potentially reducing the bandwidth consumed by your origin server.

Use this setting to turn on or off Hotlink Protection for matching requests.

API information

API configuration property name: `"hotlink_protection"` (boolean).

API configuration example

```

"action_parameters": {

    "hotlink_protection": false

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## I'm Under Attack

When enabled, [Under Attack mode](https://developers.cloudflare.com/fundamentals/reference/under-attack-mode/) performs additional security checks to help mitigate layer 7 DDoS attacks. Validated users access your website and suspicious traffic is blocked.

Use this setting to turn on or off Under Attack mode for matching requests.

API information

API configuration property name: `"security_level"` (string).

API values: `"off"`, `"essentially_off"`, `"under_attack"`.

API configuration example

```

"action_parameters": {

  "security_level": "under_attack"

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## Markdown for Agents

[Markdown for Agents](https://developers.cloudflare.com/fundamentals/reference/markdown-for-agents/) automatically converts HTML to Markdown for requests that use content negotiation headers (`Accept: text/markdown`).

Use this setting to turn on or off Markdown for Agents for matching requests.

API information

API configuration property name: `"content_converter"` (boolean).

API configuration example

```

"action_parameters": {

  "content_converter": true

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## Opportunistic Encryption

[Opportunistic Encryption](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/opportunistic-encryption/) allows browsers to access HTTP URIs over an encrypted TLS channel.

Use this setting to turn on or off Opportunistic Encryption for matching requests.

API information

API configuration property name: `"opportunistic_encryption"` (boolean).

API configuration example

```

"action_parameters": {

  "opportunistic_encryption": true

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## Polish

[Cloudflare Polish](https://developers.cloudflare.com/images/polish/) is a one-click image optimization product that automatically optimizes images in your site.

Use this setting to configure Polish for matching requests:

* Off
* Lossless
* Lossy
* WebP

Refer to [Compression options](https://developers.cloudflare.com/images/polish/compression/#compression-options) for more information on these values.

API information

API configuration property name: `"polish"` (string).

API values: `"off"`, `"lossless"`, `"lossy"`, `"webp"`.

API configuration example

```

"action_parameters": {

  "polish": "webp"

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## Request Body Buffering

Use the Request Body Buffering setting to configure the request body buffering mode for matching requests:

* **Standard** (default): Allows Cloudflare products to inspect a prefix of the request body when necessary for enabled functionality on your zone.
* **Full**: Buffers the entire request body before sending the request to your origin server.
* **None**: Strictly no buffering. The request body is streamed directly to the origin server without inspection.

This setting only takes effect on zones running Cloudflare's [latest CDN proxy ↗](https://blog.cloudflare.com/20-percent-internet-upgrade/). Enterprise customers can contact their account team to enable the latest proxy on their zones.

Warning

Setting request body buffering to **None** may break functionality that requires body inspection. In particular, this can impact the effectiveness of the Web Application Firewall (WAF) and other security features that rely on analyzing request bodies to detect and block threats.

API information

API configuration property name: `"request_body_buffering"` (string).

API values: `"standard"`, `"full"`, `"none"`.

API configuration example

```

"action_parameters": {

  "request_body_buffering": "full"

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## Response Body Buffering

Use the Response Body Buffering setting to configure the response body buffering mode for matching requests:

* **Standard** (default): Allows Cloudflare products to inspect a prefix of the response body when necessary for enabled functionality on your zone.
* **None**: Strictly no buffering. The response body is streamed directly to the client without inspection.

This setting only takes effect on zones running Cloudflare's [latest CDN proxy ↗](https://blog.cloudflare.com/20-percent-internet-upgrade/). Enterprise customers can contact their account team to enable the latest proxy on their zones.

Warning

Setting response body buffering to **None** may break functionality that requires body inspection. In particular, this can impact the effectiveness of the Web Application Firewall (WAF) and other security features that rely on analyzing response bodies to detect and block threats.

API information

API configuration property name: `"response_body_buffering"` (string).

API values: `"standard"`, `"none"`.

API configuration example

```

"action_parameters": {

  "response_body_buffering": "standard"

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## Rocket Loader

[Rocket Loader](https://developers.cloudflare.com/speed/optimization/content/rocket-loader/) prioritizes your website's content (such as text, images, and fonts) by deferring the loading of all your JavaScript code until after rendering.

Use this setting to turn on or off Rocket Loader for matching requests.

API information

API configuration property name: `"rocket_loader"` (boolean).

API configuration example

```

"action_parameters": {

  "rocket_loader": true

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

## SSL

[SSL/TLS encryption modes](https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/) control the scheme (`http://` or `https://`) that Cloudflare uses to connect to your origin web server and how SSL certificates presented by your origin will be validated.

Use this setting to configure the SSL/TLS encryption mode for matching requests:

* Off
* Flexible
* Full
* Strict
* Origin Pull

Refer to [Available encryption modes](https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/#available-encryption-modes) for more information on these values.

API information

API configuration property name: `"ssl"` (string).

API values: `"off"`, `"flexible"`, `"full"`, `"strict"`, `"origin_pull"`.

API configuration example

```

"action_parameters": {

  "ssl": "flexible"

}


```

Refer to [Create a configuration rule via API](https://developers.cloudflare.com/rules/configuration-rules/create-api/#example-requests) for complete API examples.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/configuration-rules/","name":"Configuration Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/configuration-rules/settings/","name":"Configuration Rules settings"}}]}
```

---

---
title: Cloudflare Snippets
description: Cloudflare Snippets provide a powerful and flexible way to customize the behavior of your website or application using short pieces of JavaScript code. With Snippets, you can modify HTTP response headers, implement JWT validation, perform complex redirects, and much more.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cloudflare Snippets

Cloudflare Snippets provide a powerful and flexible way to customize the behavior of your website or application using short pieces of JavaScript code. With Snippets, you can modify HTTP response headers, implement JWT validation, perform complex redirects, and much more.

For code samples addressing common use cases, please refer to the [Examples](https://developers.cloudflare.com/rules/snippets/examples/) section.

Note

Snippets require that you [proxy the DNS records](https://developers.cloudflare.com/dns/proxy-status/) of your domain (or subdomain) through Cloudflare.

## Snippets elements

To create and deploy a snippet, you need to define the following elements:

* **Code snippet**: JavaScript code to be executed during the request-handling process.
* **Snippet rule**: A [filter expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/) that determines which requests the Snippet will be applied to. Each snippet can only be associated with one snippet rule.

For more information, refer to [How Snippets work](https://developers.cloudflare.com/rules/snippets/how-it-works/) and [Create a snippet in the dashboard](https://developers.cloudflare.com/rules/snippets/create-dashboard/).

Note

If you have used the Cloudflare API to create a code snippet that is not associated with a snippet rule, the Cloudflare dashboard will show that code snippet in a separate tab called **Unused Snippets**. You can either edit the snippet code and associate it with a snippet rule, or delete the unused code snippet.

## Templates

Cloudflare provides you with rules templates for common use cases.

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Templates**, and then select one of the available templates.

You can also refer to the [Examples gallery](https://developers.cloudflare.com/rules/examples/) in the developer docs.

## Availability

| Free                          | Pro | Business | Enterprise |     |
| ----------------------------- | --- | -------- | ---------- | --- |
| Availability                  | No  | Yes      | Yes        | Yes |
| Number of snippets            | 0   | 25       | 50         | 300 |
| Number of snippet subrequests | 0   | 2        | 3          | 5   |

Each subrequest in a redirect chain counts against the subrequest limit. This means that if a subrequest was redirected it would count as two subrequests. To avoid issues, ensure that you make a subrequest to the end location of the redirect chain.

Currently, [Version Management](https://developers.cloudflare.com/version-management/) does not support Snippets.

## Limits

Cloudflare Snippets are designed for fast, lightweight edge logic. The following limits apply:

| Description                | All plans |
| -------------------------- | --------- |
| Maximum execution time     | 5 ms      |
| Maximum memory             | 2 MB      |
| Maximum total package size | 32 KB     |

Need guidance on choosing between Snippets and Workers? 

Explore our [detailed guide](https://developers.cloudflare.com/rules/snippets/when-to-use/) for best practices, real-world use cases, and example implementations.

## Execution order

The execution order of Rules features is the following:

* [Single Redirects](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/)
* [URL Rewrite Rules](https://developers.cloudflare.com/rules/transform/url-rewrite/)
* [Configuration Rules](https://developers.cloudflare.com/rules/configuration-rules/)
* [Origin Rules](https://developers.cloudflare.com/rules/origin-rules/)
* [Bulk Redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/)
* [Managed Transforms](https://developers.cloudflare.com/rules/transform/managed-transforms/)
* [Request Header Transform Rules](https://developers.cloudflare.com/rules/transform/request-header-modification/)
* [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/)
* [Snippets](https://developers.cloudflare.com/rules/snippets/)
* [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/)

The different types of rules listed above will take precedence over [Page Rules](https://developers.cloudflare.com/rules/page-rules/). This means that Page Rules will be overridden if there is a match for both Page Rules and the Rules products listed above.

Generally speaking, for [non-terminating actions](https://developers.cloudflare.com/ruleset-engine/rules-language/actions/) the last change made by rules in the same [phase](https://developers.cloudflare.com/ruleset-engine/about/phases/) will win (later rules can overwrite changes done by previous rules). However, for terminating actions (_Block_, _Redirect_, or one of the challenge actions), rule evaluation will stop and the action will be executed immediately.

For example, if multiple rules with the _Redirect_ action match, Cloudflare will always use the URL redirect of the first rule that matches. Also, if you configure URL redirects using different Cloudflare products (Single Redirects and Bulk Redirects), the product executed first will apply, if there is a rule match (in this case, Single Redirects).

Refer to the [Phases list](https://developers.cloudflare.com/ruleset-engine/reference/phases-list/) for the product execution order.

Warning

Using Cloudflare challenges along with Rules features may cause challenge loops. Refer to [Rules troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/) for more information.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}}]}
```

---

---
title: Configure Snippets via API
description: You can create Snippets using the Cloudflare API.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/create-api.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Configure Snippets via API

You can create Snippets using the [Cloudflare API](https://developers.cloudflare.com/fundamentals/api/).

## Required permissions

The [API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) used in API requests to manage Snippets must have at least the following permission:

* _Zone_ \> _Snippets_ \> _Edit_

Note

A token with this permission is only valid for the Snippets endpoints described in this page. You cannot use it to interact with the `http_request_snippets` phase via [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/).

## Endpoints

To obtain the complete endpoint, append the Snippets endpoints listed below to the Cloudflare API base URL:

```

https://api.cloudflare.com/client/v4


```

The `{zone_id}` argument is the [zone ID](https://developers.cloudflare.com/fundamentals/account/find-account-and-zone-ids/) (a hexadecimal string). You can find this value in the Cloudflare dashboard.

The following table summarizes the available operations.

| Operation                          | Verb + Endpoint                                        |
| ---------------------------------- | ------------------------------------------------------ |
| List all code snippets             | GET /zones/{zone\_id}/snippets                         |
| Create/update code snippet         | PUT /zones/{zone\_id}/snippets/{snippet\_name}         |
| Get code snippet details           | GET /zones/{zone\_id}/snippets/{snippet\_name}         |
| Get code snippet content           | GET /zones/{zone\_id}/snippets/{snippet\_name}/content |
| Delete code snippet                | DELETE /zones/{zone\_id}/snippets/{snippet\_name}      |
| List snippet rules                 | GET /zones/{zone\_id}/snippets/snippet\_rules          |
| Create/update/delete snippet rules | PUT /zones/{zone\_id}/snippets/snippet\_rules          |
| Delete all snippet rules           | DELETE /zones/{zone\_id}/snippets/snippet\_rules       |

## Example API calls

### Create/update code snippet

To create or update a Snippet, use the following `PUT` request. The snippet is named `$SNIPPET_NAME` and the body contains the JavaScript code.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Snippets Write`

Update a zone snippet

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/snippets/$SNIPPET_NAME" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --form "files=@example.js" \

  --form "metadata={\"main_module\": \"example.js\"}"


```

The name of a snippet can only contain the characters `a-z`, `0-9`, and `_` (underscore). The name must be unique in the context of the zone. You cannot change the snippet name after creating the snippet.

The required body parameters are:

* `files`: The file with your JavaScript code.
* `metadata`: Object containing `main_module`, which must match the filename of the uploaded file.

To make this example work, save your JavaScript code in a file named `example.js`, and then execute `curl` command with a `PUT` request from the folder where `example.js` is located.

Example response

```

{

  "errors": [],

  "messages": [],

  "success": true,

  "result": {

    "created_on": "2023-07-24-00:00:00",

    "modified_on": "2023-07-24-00:00:00",

    "snippet_name": "snippet_name_01"

  }

}


```

To deploy a new snippet you must [create a snippet rule](#createupdatedelete-snippet-rules). The expression of the snippet rule defines when the snippet code will run.

### Create/update/delete snippet rules

Warning

When using this endpoint to create a new rule and keep existing rules, you must include all rules in the request body. Omitting an existing rule will delete the corresponding rule.

Once you have created a code snippet, you can link it to rules. This is done via the following `PUT` request to the `snippet_rules` endpoint.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Snippets Write`

Update zone snippet rules

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/snippets/snippet_rules" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "description": "Trigger snippet on specific cookie",

            "enabled": true,

            "expression": "http.cookie eq \"a=b\"",

            "snippet_name": "snippet_name_01"

        }

    ]

  }'


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/create-api/","name":"Configure Snippets via API"}}]}
```

---

---
title: Create a snippet in the dashboard
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/create-dashboard.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a snippet in the dashboard

1. In the Cloudflare dashboard, go to the **Snippets** page.  
[ Go to **Snippets** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/snippets)
2. (Optional) If you have not created any snippets yet, select one of the snippet templates that addresses a common use case. Then, review and adjust the proposed snippet code.  
To start from scratch, select **Create Snippet**.
3. In **Snippet name**, enter a descriptive name for the snippet. You cannot change the name after creating the snippet.
4. Enter the snippet's JavaScript code in the code editor. You can test how your snippet will handle incoming requests using the **HTTP** and **Preview** tabs.
5. Select **Snippet rule** to configure when the snippet will run.
6. Under **Run this Snippet if incoming requests match**, select if you wish to run the snippet only for requests that match a custom filter expression or for all incoming requests.
7. (Optional) To define a custom expression, use the Expression Builder (specifying one or more values for **Field**, **Operator**, and **Value**) or manually enter an expression using the Expression Editor. For more information, refer to [Edit expressions in the dashboard](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/).
8. Select **Done**.
9. To deploy your snippet, select **Deploy**. If you are not ready to deploy your snippet, open the dropdown next to **Deploy** and select **Save as Draft**.  
If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to [Troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/#this-rule-may-not-apply-to-your-traffic) for more information.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/create-dashboard/","name":"Create a snippet in the dashboard"}}]}
```

---

---
title: Configure Snippets using Terraform
description: You can create Snippets using the Terraform Cloudflare provider.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/create-terraform.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Configure Snippets using Terraform

You can create Snippets using the [Terraform Cloudflare provider ↗](https://registry.terraform.io/providers/cloudflare/cloudflare/latest).

To get started with Terraform for Cloudflare configuration, refer to [Get started](https://developers.cloudflare.com/terraform/installing/).

## Example configuration

Note

Terraform code snippets below refer to the v4 SDK only.

The following example Terraform configuration creates a snippet and an associated snippet rule that defines when the snippet code will run. The snippet code is loaded from the `file1.js` file in your machine.

```

resource "cloudflare_snippet" "my_snippet" {

  zone_id  = "<ZONE_ID>"

  name = "my_test_snippet_1"

  main_module = "file1.js"

  files {

    name = "file1.js"

    content = file("file1.js")

  }

}


resource "cloudflare_snippet_rules" "cookie_snippet_rule" {

  zone_id  = "<ZONE_ID>"

  rules {

    enabled = true

    expression = "http.cookie eq \"a=b\""

    description = "Trigger snippet on specific cookie"

    snippet_name = "my_test_snippet_1"

  }

  depends_on = [cloudflare_snippet.my_snippet]

}


```

The name of a snippet can only contain the characters `a-z`, `0-9`, and `_` (underscore). The name must be unique in the context of the zone. You cannot change the snippet name after creating the snippet.

All `snippet_name` values in the `cloudflare_snippet_rules` resource must match the names of existing snippets.

## More resources

Refer to the [Terraform Cloudflare provider documentation ↗](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs) for more information on the `cloudflare_snippet` and `cloudflare_snippet_rules` resources.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/create-terraform/","name":"Configure Snippets using Terraform"}}]}
```

---

---
title: Troubleshoot Snippets
description: This error occurs when a Snippet attempts to call fetch(request) more than once.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/errors.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Troubleshoot Snippets

## Error 1201: Snippet tried to continue to origin multiple times

This error occurs when a Snippet attempts to call `fetch(request)` more than once.

### Resolution

Ensure that your Snippet code only calls `fetch(request)` once. This method is used to send the modified request to the origin server, and it should be called only once per Snippet to avoid conflicts.

## Error 1202: Snippets exceeded subrequests limit

This error occurs when the number of subrequests exceeds [the limit](https://developers.cloudflare.com/rules/snippets/#availability) for your Cloudflare plan.

### Resolution

Review your Snippet to ensure your code is within the subrequest [limits](https://developers.cloudflare.com/rules/snippets/#availability) for your plan. Each subrequest counts against your limit, including any redirects within a subrequest chain.

## Error 1203: Snippets exceeded CPU time limit

This error occurs when a Snippet exceeds the defined [CPU time limit](https://developers.cloudflare.com/rules/snippets/#limits) for Snippets.

### Resolution

Review your Snippet to ensure your code is within the CPU time limit. If you need a higher CPU time limit, consider using [Cloudflare Workers](https://developers.cloudflare.com/workers/). Refer to [When to use Snippets vs Workers](https://developers.cloudflare.com/rules/snippets/when-to-use/) for details.

## Error 1204: Snippets exceeded memory limit

This error occurs when a Snippet exceeds the defined [memory limit](https://developers.cloudflare.com/rules/snippets/#limits) for Snippets.

### Resolution

Review your Snippet to ensure your code is within the memory limit. If you need a higher memory limit, consider using [Cloudflare Workers](https://developers.cloudflare.com/workers/). Refer to [When to use Snippets vs Workers](https://developers.cloudflare.com/rules/snippets/when-to-use/) for details.

## Error 1205: Deployment in progress

A new Snippet was just deployed and is currently propagating across Cloudflare's global network. During this short window, requests may not be processed as expected.

### Resolution

This is a temporary issue. Retry your request after a few seconds — the Snippet will be active once propagation completes.

## Error 1206: Snippet threw exception

The Snippet encountered an unhandled JavaScript exception during execution. This may be caused by one of the following:

* Runtime JavaScript errors in Snippet code
* Unhandled promise rejections
* Type errors or reference errors

### Resolution

* Review the Snippet code to identify where the exception might have occurred and fix any detected bugs.
* Add proper error handling ([try...catch ↗](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch) blocks).

## Snippets cannot be renamed

The name you define when creating a Snippet will be used as the Snippet ID and cannot be edited afterwards.

### Resolution

To change the name of your Snippet, create a new Snippet and delete the old one.

---

## Other runtime errors

Snippets share some error codes with Workers, namely errors in the `11xx` range. For more information on these errors, refer to [Errors and exceptions](https://developers.cloudflare.com/workers/observability/errors/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/errors/","name":"Troubleshoot Snippets"}}]}
```

---

---
title: Snippets examples
description: Refer to the following examples to get started creating your snippet code.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Snippets examples

Refer to the following examples to get started creating your snippet code.

Refer to [How Snippets work](https://developers.cloudflare.com/rules/snippets/how-it-works/) and [Create a snippet in the dashboard](https://developers.cloudflare.com/rules/snippets/create-dashboard/) for overall guidance.

Filter resources...

[A/B testing with same-URL direct accessSet up an A/B test by controlling what response is served based on cookies.](https://developers.cloudflare.com/rules/snippets/examples/ab-testing-same-url/)[Append dates to cookies to use with A/B testingDynamically set a cookie expiration and test group.](https://developers.cloudflare.com/rules/snippets/examples/append-dates-to-cookies/)[Auth with headersAllow or deny a request based on a known pre-shared key in a header. This is not meant to replace the WebCrypto API.](https://developers.cloudflare.com/rules/snippets/examples/auth-with-headers/)[Send Bot Management information to originSend Bots information to your origin. Refer to Bot Management variables for a full list of available fields.](https://developers.cloudflare.com/rules/snippets/examples/bot-data-to-origin/)[Send suspect bots to a honeypotUse the bot score field to send bots to a honeypot.](https://developers.cloudflare.com/rules/snippets/examples/bots-to-honeypot/)[Bulk redirect based on a map objectRedirect requests to certain URLs based on a mapped object to the request's URL.](https://developers.cloudflare.com/rules/snippets/examples/bulk-redirect-map/)[Country code redirectRedirect a response based on the country code in the header of a visitor.](https://developers.cloudflare.com/rules/snippets/examples/country-code-redirect/)[Custom cacheStore, retrieve, and remove assets from cache programmatically. Use this template to optimize performance and implement custom caching strategies.](https://developers.cloudflare.com/rules/snippets/examples/custom-cache/)[Debugging logsSend debugging information in an errored response to a logging service.](https://developers.cloudflare.com/rules/snippets/examples/debugging-logs/)[Define CORS headersAdjust Cross-Origin Resource Sharing (CORS) headers and handle preflight requests.](https://developers.cloudflare.com/rules/snippets/examples/define-cors-headers/)[Follow redirects from the originModify the fetch request to follow redirects from the origin, ensuring the client receives the final response.](https://developers.cloudflare.com/rules/snippets/examples/follow-redirects/)[Add HEX timestamp to a request headerAdd a custom header to requests sent to the origin server with the current timestamp in hexadecimal format for debugging, tracking, or custom routing purposes.](https://developers.cloudflare.com/rules/snippets/examples/hex-timestamp/)[Validate JSON web tokens (JWT)Extract the JWT token from a header, decode it, and implement validation checks to verify it.](https://developers.cloudflare.com/rules/snippets/examples/jwt-validation/)[Maintenance pageServe a custom maintenance page instead of fetching content from the origin server or cache. Ideal for downtime notifications, planned maintenance, or emergency messages.](https://developers.cloudflare.com/rules/snippets/examples/maintenance/)[Override a Set-Cookie header with a certain valueGet a specific Set-Cookie header and update it with a certain value.](https://developers.cloudflare.com/rules/snippets/examples/override-set-cookies-value/)[Redirect 403 Forbidden to a different pageIf origin responded with 403 Forbidden error code, redirect to different page.](https://developers.cloudflare.com/rules/snippets/examples/redirect-forbidden-status/)[Redirect from one domain to anotherRedirect all requests from one domain to another domain.](https://developers.cloudflare.com/rules/snippets/examples/redirect-replaced-domain/)[Remove fields from API responseIf origin responds with JSON, parse the response and delete fields to return a modified response.](https://developers.cloudflare.com/rules/snippets/examples/remove-fields-api-response/)[Remove query strings before sending request to originRemove certain query strings from a request before passing to the origin.](https://developers.cloudflare.com/rules/snippets/examples/remove-query-strings/)[Remove response headersRemove from response all headers that start with a certain name.](https://developers.cloudflare.com/rules/snippets/examples/remove-response-headers/)[Return information about the incoming requestRespond with information about the incoming request provided by Cloudflare’s global network.](https://developers.cloudflare.com/rules/snippets/examples/return-incoming-request-properties/)[Rewrite links on HTML pagesDynamically rewrite links in HTML responses. This is useful for site migrations and branding updates.](https://developers.cloudflare.com/rules/snippets/examples/rewrite-site-links/)[Change origin and modify pathsRoute requests to a different origin, prepend a directory to the URL path, and remove specific segments.](https://developers.cloudflare.com/rules/snippets/examples/route-and-rewrite/)[Set security headersSet common security headers such as X-XSS-Protection, X-Frame-Options, and X-Content-Type-Options.](https://developers.cloudflare.com/rules/snippets/examples/security-headers/)[Send timestamp to origin as a custom headerConvert timestamp to hexadecimal format and send it as a custom header to the origin.](https://developers.cloudflare.com/rules/snippets/examples/send-timestamp-to-origin/)[Route to a different origin based on origin responseIf response to the original request is not 200 OK or a redirect, send to another origin.](https://developers.cloudflare.com/rules/snippets/examples/serve-different-origin/)[Sign requestsVerify a signed request using the HMAC and SHA-256 algorithms or return a 403.](https://developers.cloudflare.com/rules/snippets/examples/signing-requests/)[Slow down suspicious requestsDefine a delay to be used when incoming requests match a rule you consider suspicious based on the bot score.](https://developers.cloudflare.com/rules/snippets/examples/slow-suspicious-requests/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}}]}
```

---

---
title: A/B testing with same-URL direct access
description: Set up an A/B test by controlling what response is served based on cookies.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ A/B testing ](https://developers.cloudflare.com/search/?tags=A/B%20testing)[ Cookies ](https://developers.cloudflare.com/search/?tags=Cookies)[ URL rewrite ](https://developers.cloudflare.com/search/?tags=URL%20rewrite) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/ab-testing-same-url.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# A/B testing with same-URL direct access

Set up an A/B test by controlling what response is served based on cookies.

This version passes through requests for `/test/*` and `/control/*` URI paths to the origin server, bypassing random assignment.

JavaScript

```

const NAME = "myExampleABTest";


export default {

  async fetch(request) {

    // Clone the original URL

    const url = new URL(request.url);


    // Enable Passthrough to allow direct access to control and test routes.

    if (url.pathname.startsWith("/control") || url.pathname.startsWith("/test"))

      return fetch(request);


    // Determine which group this requester is in.

    const cookie = request.headers.get("cookie");


    if (cookie && cookie.includes(`${NAME}=control`)) {

      url.pathname = "/control" + url.pathname;

    } else if (cookie && cookie.includes(`${NAME}=test`)) {

      url.pathname = "/test" + url.pathname;

    } else {

      // If there is no cookie, this is a new client. Choose a group and set the cookie.

      const group = Math.random() < 0.5 ? "test" : "control"; // 50/50 split

      if (group === "control") {

        url.pathname = "/control" + url.pathname;

      } else {

        url.pathname = "/test" + url.pathname;

      }

      // Reconstruct response to avoid immutability

      let response = await fetch(url);

      response = new Response(response.body, response);

      // Set cookie to enable persistent A/B sessions.

      response.headers.append("Set-Cookie", `${NAME}=${group}; path=/`);

      return response;

    }

    return fetch(url);

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/ab-testing-same-url/","name":"A/B testing with same-URL direct access"}}]}
```

---

---
title: Append dates to cookies to use with A/B testing
description: Dynamically set a cookie expiration and test group.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ A/B testing ](https://developers.cloudflare.com/search/?tags=A/B%20testing)[ Cookies ](https://developers.cloudflare.com/search/?tags=Cookies) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/append-dates-to-cookies.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Append dates to cookies to use with A/B testing

Dynamically set a cookie expiration and test group.

JavaScript

```

export default {

  async fetch(request) {

    const response = await fetch(request);


    // Clone the response so that it is no longer immutable

    const newResponse = new Response(response.body, response);


    // Define the dynamic expiry time. 24 h * 60 m * 60 s * 1000 ms = 86,400,000 ms

    const expiry = new Date(Date.now() + 7 * 86400000).toUTCString();

    // Define the group variable. "A" if the request header "userGroup" is "premium", "B" if otherwise.

    const group = request.headers.get("userGroup") == "premium" ? "A" : "B";


    // Append the custom header with the values

    newResponse.headers.append(

      "Set-Cookie",

      `testGroup=${group}; Expires=${expiry}; Path=/`,

    );


    return newResponse;

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/append-dates-to-cookies/","name":"Append dates to cookies to use with A/B testing"}}]}
```

---

---
title: Auth with headers
description: Allow or deny a request based on a known pre-shared key in a header. This is not meant to replace the [WebCrypto API](/workers/runtime-apis/web-crypto/).
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Authentication ](https://developers.cloudflare.com/search/?tags=Authentication)[ Request modification ](https://developers.cloudflare.com/search/?tags=Request%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/auth-with-headers.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Auth with headers

Allow or deny a request based on a known pre-shared key in a header. This is not meant to replace the [WebCrypto API](https://developers.cloudflare.com/workers/runtime-apis/web-crypto/).

Caution when using in production

The example code contains a generic header key and value of `X-Custom-PSK` and `mypresharedkey`. To best protect your resources, change the header key and value in the Snippets editor before saving your code.

JavaScript

```

export default {

  async fetch(request) {

    /**

     * @param {string} PRESHARED_AUTH_HEADER_KEY Custom header to check for key

     * @param {string} PRESHARED_AUTH_HEADER_VALUE Hard-coded key value

     */

    const PRESHARED_AUTH_HEADER_KEY = "X-Custom-PSK";

    const PRESHARED_AUTH_HEADER_VALUE = "mypresharedkey";

    const psk = request.headers.get(PRESHARED_AUTH_HEADER_KEY);


    if (psk === PRESHARED_AUTH_HEADER_VALUE) {

      // Correct preshared header key supplied. Fetch request from origin.

      return fetch(request);

    }


    // Incorrect key supplied. Reject the request.

    return new Response("Sorry, you have supplied an invalid key.", {

      status: 403,

    });

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/auth-with-headers/","name":"Auth with headers"}}]}
```

---

---
title: Send Bot Management information to origin
description: Send [Bots](/bots/) information to your origin. Refer to [Bot Management variables](/bots/reference/bot-management-variables/) for a full list of available fields.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Headers ](https://developers.cloudflare.com/search/?tags=Headers)[ Request modification ](https://developers.cloudflare.com/search/?tags=Request%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/bot-data-to-origin.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Send Bot Management information to origin

Send [Bots](https://developers.cloudflare.com/bots/) information to your origin. Refer to [Bot Management variables](https://developers.cloudflare.com/bots/reference/bot-management-variables/) for a full list of available fields.

JavaScript

```

export default {

  async fetch(request) {

    // Clone the original request to construct a new request

    const newRequest = new Request(request);

    // Set Bot Management headers on a new request to the origin: https://developers.cloudflare.com/bots/reference/bot-management-variables/#workers-variables

    newRequest.headers.set("bot-score", request.cf.botManagement.score); // bot score (integer)

    newRequest.headers.set(

      "verified-bot",

      request.cf.botManagement.verifiedBot,

    ); // verified bot (boolean)

    newRequest.headers.set("ja4", request.cf.botManagement.ja4); // JA4 fingerprint hash (string)

    // Serve response to the new request from the origin

    return await fetch(newRequest);

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/bot-data-to-origin/","name":"Send Bot Management information to origin"}}]}
```

---

---
title: Send suspect bots to a honeypot
description: Use the [bot score field](/workers/runtime-apis/request/#incomingrequestcfproperties) to send bots to a honeypot.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Redirects ](https://developers.cloudflare.com/search/?tags=Redirects) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/bots-to-honeypot.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Send suspect bots to a honeypot

Use the [bot score field](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties) to send bots to a honeypot.

JavaScript

```

export default {

  async fetch(request) {

    const response = await fetch(request);


    // Clone the response so that it is no longer immutable

    const newResponse = new Response(response.body, response);


    if (request.cf.botManagement.score < 30) {

      const honeypot = "https://example.com/";

      return await fetch(honeypot, request);

    } else {

      return newResponse;

    }

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/bots-to-honeypot/","name":"Send suspect bots to a honeypot"}}]}
```

---

---
title: Bulk redirect based on a map object
description: Redirect requests to certain URLs based on a mapped object to the request's URL.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Redirects ](https://developers.cloudflare.com/search/?tags=Redirects) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/bulk-redirect-map.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Bulk redirect based on a map object

Redirect requests to certain URLs based on a mapped object to the request's URL.

JavaScript

```

export default {

  async fetch(request) {

    // Define a variable with the hostname that needs to be redirected.

    const externalHostname = "example.com";


    // Define the map object. Replace the sources (/pathX) and targets (/redirectX) with ones that apply to your case.

    const redirectMap = new Map([

      ["/path1", "https://" + externalHostname + "/redirect1"],

      ["/path2", "https://" + externalHostname + "/redirect2"],

      ["/path3", "https://" + externalHostname + "/redirect3"],

      ["/path4", "https://cloudflare.com"],

    ]);


    // Clone the original URL.

    const requestURL = new URL(request.url);


    // Check the request path against the map and redirect accordingly.

    const path = requestURL.pathname;

    const location = redirectMap.get(path);


    if (location) {

      return Response.redirect(location, 301);

    }


    // If request path not in map, return the original request.

    return fetch(request);

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/bulk-redirect-map/","name":"Bulk redirect based on a map object"}}]}
```

---

---
title: Country code redirect
description: Redirect a response based on the country code in the header of a visitor.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Localization ](https://developers.cloudflare.com/search/?tags=Localization)[ Redirects ](https://developers.cloudflare.com/search/?tags=Redirects) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/country-code-redirect.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Country code redirect

Redirect a response based on the country code in the header of a visitor.

JavaScript

```

export default {

  async fetch(request) {

    /**

     * A map of the URLs to redirect to

     * @param {Object} countryMap

     */

    const countryMap = {

      // Replace the country codes and target URLs with ones that apply to your case.

      US: "https://example.com/us",

      EU: "https://example.com/eu",

    };


    // Use the cf object to obtain the country of the request

    // more on the cf object: https://developers.cloudflare.com/workers/runtime-apis/request#incomingrequestcfproperties

    const country = request.cf.country;


    // If country is not null and is defined in the country map above, redirect.

    if (country != null && country in countryMap) {

      const url = countryMap[country];

      // Remove this logging statement from your final output.

      console.log(

        `Based on ${country}-based request, your user would go to ${url}.`,

      );

      return Response.redirect(url);


      // If request country not in map, return another page.

    } else {

      return fetch("https://example.com", request);

    }

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/country-code-redirect/","name":"Country code redirect"}}]}
```

---

---
title: Custom cache
description: Store, retrieve, and remove assets from cache programmatically. Use this template to optimize performance and implement custom caching strategies.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Caching ](https://developers.cloudflare.com/search/?tags=Caching) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/custom-cache.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Custom cache

Control cache programmatically. Use this template to optimize performance and implement custom caching strategies.

JavaScript

```

// Define configurable cache duration in seconds (default: 30 days)

const CACHE_DURATION_SECONDS = 30 * 24 * 60 * 60;


// Define which parts of the request to include in the cache key

const USE_PATH = true; // Include path in the cache key

const USE_QUERY_STRING = true; // Include query string in the cache key

const INCLUDE_HEADERS = ["User-Agent"]; // Headers to include in the cache key


export default {

  async fetch(request, env, ctx) {

    // Generate a custom cache key based on user preferences

    const cacheKey = createCacheKey(request);

    console.log(`Retrieving cache for: ${cacheKey.url}.`);


    // Access the default Cache API

    const cache = caches.default;


    // Attempt to retrieve the cached response

    let response = await cache.match(cacheKey);


    if (!response) {

      // Cache miss: Fetch the asset from the origin

      console.log(`Cache miss for: ${cacheKey.url}. Fetching from origin...`);

      response = await fetch(request);


      // Wrap the origin response for caching

      response = new Response(response.body, response);


      // Set Cache-Control headers to define the TTL

      response.headers.set(

        "Cache-Control",

        `s-maxage=${CACHE_DURATION_SECONDS}`,

      );

      response.headers.set("x-snippets-cache", "stored");


      // Store the response in the cache

      await cache.put(cacheKey, response.clone());

    } else {

      // Cache hit: Return the cached response

      console.log(`Cache hit for: ${cacheKey.url}.`);

      response = new Response(response.body, response);

      response.headers.set("x-snippets-cache", "hit");


      // Optionally check if the cache should expire based on age

      const ageHeader = response.headers.get("Age");

      if (ageHeader && parseInt(ageHeader, 10) > CACHE_DURATION_SECONDS) {

        console.log(

          `Cache expired for: ${cacheKey.url}. Deleting cached response...`,

        );

        await cache.delete(cacheKey);

        response.headers.set("x-snippets-cache", "deleted");

      }

    }


    // Return the response to the client

    return response;

  },

};


/**

 * Function to create a custom cache key based on request properties

 * @param {Request} request - The incoming request object

 * @returns {Request} - A valid cache key based on the URL

 */

function createCacheKey(request) {

  const url = new URL(request.url); // Use the request's base URL

  const cacheKey = new URL(url.origin); // Start with the origin (scheme + hostname)


  // Optionally include the path

  if (USE_PATH) {

    cacheKey.pathname = url.pathname;

  }


  // Optionally include the query string

  if (USE_QUERY_STRING) {

    cacheKey.search = url.search;

  }


  // Optionally include specific headers

  if (INCLUDE_HEADERS.length > 0) {

    const headerParts = INCLUDE_HEADERS.map(

      (header) => `${header}=${request.headers.get(header) || ""}`,

    ).join("&");

    cacheKey.searchParams.append("headers", headerParts);

  }


  // Return the constructed URL as the cache key

  return new Request(cacheKey.toString(), {

    method: "GET",

  });

}


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/custom-cache/","name":"Custom cache"}}]}
```

---

---
title: Debugging logs
description: Send debugging information in an errored response to a logging service.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Logging ](https://developers.cloudflare.com/search/?tags=Logging)[ Response modification ](https://developers.cloudflare.com/search/?tags=Response%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/debugging-logs.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Debugging logs

Send debugging information in an errored response to a logging service.

JavaScript

```

// Replace with your actual logging service endpoint

const loggingEndpoint = "https://your-logging-endpoint";


export default {

  async fetch(request) {

    try {

      // Attempt to fetch the request from the origin server

      const response = await fetch(request.clone());


      // Check if the response status indicates an error (for example, 4xx or 5xx)

      if (!response.ok) {

        // Prepare error details and context for logging

        const errorDetails = {

          status: response.status,

          statusText: response.statusText,

          url: request.url,

          method: request.method,

          headers: Object.fromEntries(request.headers),

        };


        // Log error details to your logging service

        await logError(errorDetails);


        // Return the original response with status and statusText intact

        return new Response(response.body, {

          status: response.status,

          statusText: response.statusText,

          headers: response.headers,

        });

      }


      // Return the successful response from the origin server

      return response;

    } catch (error) {

      // Handle any exceptions that occur during fetch

      const errorDetails = {

        message: error.message,

        stack: error.stack,

        url: request.url,

        method: request.method,

        headers: Object.fromEntries(request.headers),

      };


      // Log error details to your logging service

      await logError(errorDetails);


      // Return a generic error response

      return new Response("Internal Server Error", {

        status: 500,

      });

    }

  },

};


// Function to log error details to your logging service

async function logError(details) {

  try {

    const response = await fetch(loggingEndpoint, {

      method: "POST",

      headers: {

        "Content-Type": "application/json",

      },

      body: JSON.stringify(details),

    });


    if (!response.ok) {

      console.error("Failed to log error:", response.statusText);

    }

  } catch (error) {

    console.error("Error logging error:", error.message);

  }

}


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/debugging-logs/","name":"Debugging logs"}}]}
```

---

---
title: Define CORS headers
description: Adjust [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) headers and handle preflight requests.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Headers ](https://developers.cloudflare.com/search/?tags=Headers)[ Request modification ](https://developers.cloudflare.com/search/?tags=Request%20modification)[ Response modification ](https://developers.cloudflare.com/search/?tags=Response%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/define-cors-headers.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Define CORS headers

Adjust [Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) headers and handle preflight requests.

JavaScript

```

// Define CORS headers

const corsHeaders = {

  "Access-Control-Allow-Origin": "*", // Replace * with your allowed origin(s)

  "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS", // Adjust allowed methods as needed

  "Access-Control-Allow-Headers": "Content-Type, Authorization", // Adjust allowed headers as needed

  "Access-Control-Max-Age": "86400", // Adjust max age (in seconds) as needed

};


export default {

  async fetch(request) {

    // Make a copy of the request to modify its headers

    const modifiedRequest = new Request(request);


    // Handle preflight requests (OPTIONS)

    if (request.method === "OPTIONS") {

      return new Response(null, {

        headers: {

          ...corsHeaders,

        },

        status: 200, // Respond with OK status for preflight requests

      });

    }


    // Pass the modified request through to the origin

    const response = await fetch(modifiedRequest);


    // Make a copy of the response to modify its headers

    const modifiedResponse = new Response(response.body, response);


    // Set CORS headers on the response

    Object.keys(corsHeaders).forEach((header) => {

      modifiedResponse.headers.set(header, corsHeaders[header]);

    });


    return modifiedResponse;

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/define-cors-headers/","name":"Define CORS headers"}}]}
```

---

---
title: Follow redirects from the origin
description: Modify the fetch request to follow redirects from the origin, ensuring the client receives the final response.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Redirects ](https://developers.cloudflare.com/search/?tags=Redirects) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/follow-redirects.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Follow redirects from the origin

Modify the fetch request to follow redirects from the origin, ensuring the client receives the final response.

JavaScript

```

export default {

  async fetch(request) {

    // Define fetch options to follow redirects

    const fetchOptions = {

      redirect: "follow", // Ensure fetch follows redirects automatically. Each subrequest in a redirect chain counts against the subrequest limit.

    };


    // Make the fetch request to the origin

    const response = await fetch(request, fetchOptions);


    // Log the final URL after redirects (optional, for debugging)

    console.log(`Final URL after redirects: ${response.url}`);


    // Return the final response to the client

    return response;

  },

};


```

This template is ready for use and should fit most redirect-following scenarios.

It ensures the Snippet transparently follows redirects issued by the origin server. The `redirect: "follow"` option of the [Fetch API](https://developers.cloudflare.com/workers/runtime-apis/fetch/) ensures automatic handling of `3xx` redirects, returning the final response. If the origin response is not a redirect, the original content is returned.

Note

Snippets have a [maximum number of subrequests per invocation](https://developers.cloudflare.com/rules/snippets/#availability) which depends on your plan. If the origin server issues multiple redirects, each redirect subrequest will count towards this limit. When the number of subrequests exceeds the limit for your Cloudflare plan, you will receive a [1202 error](https://developers.cloudflare.com/rules/snippets/errors/#error-1202-snippets-exceeded-subrequests-limit). Ensure your origin configuration minimizes unnecessary redirects.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/follow-redirects/","name":"Follow redirects from the origin"}}]}
```

---

---
title: Add HEX timestamp to a request header
description: Add a custom header to requests sent to the origin server with the current timestamp in hexadecimal format for debugging, tracking, or custom routing purposes.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Headers ](https://developers.cloudflare.com/search/?tags=Headers)[ Request modification ](https://developers.cloudflare.com/search/?tags=Request%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/hex-timestamp.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Add HEX timestamp to a request header

Add a custom header to requests sent to the origin server with the current timestamp in hexadecimal format.

JavaScript

```

export default {

  async fetch(request) {

    // Get the current timestamp

    const timestamp = Date.now();


    // Convert the timestamp to hexadecimal format

    const hexTimestamp = timestamp.toString(16);


    // Clone the request and add the custom header

    const modifiedRequest = new Request(request, {

      headers: new Headers(request.headers),

    });

    modifiedRequest.headers.set("X-Hex-Timestamp", hexTimestamp);


    // Log the custom header for debugging

    console.log(`X-Hex-Timestamp: ${hexTimestamp}`);


    // Pass the modified request to the origin

    const response = await fetch(modifiedRequest);


    return response;

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/hex-timestamp/","name":"Add HEX timestamp to a request header"}}]}
```

---

---
title: Validate JSON web tokens (JWT)
description: Extract the JWT token from a header, decode it, and implement validation checks to verify it.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Authentication ](https://developers.cloudflare.com/search/?tags=Authentication)[ Request modification ](https://developers.cloudflare.com/search/?tags=Request%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/jwt-validation.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Validate JSON web tokens (JWT)

Extract the JWT token from a header, decode it, and implement validation checks to verify it.

JavaScript

```

export default {

  async fetch(request) {

    // Extract JWT token from "Authorization: Bearer" header

    function getJWTToken(request) {

      const authorizationHeader = request.headers.get("Authorization");

      if (authorizationHeader && authorizationHeader.startsWith("Bearer ")) {

        return authorizationHeader.substring(7, authorizationHeader.length);

      }

      return null;

    }


    // Validate that JWT token has correct format: header.payload.signature (for example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjI0OTkyMDAwLCJleHAiOjE2MjI1MDAwMDB9.TldRGokRHJvG69SefbxIqAlQ6nnco6aLa3y7jsYXHMI")

    function validateJWT(token) {

      const [header, payload, signature] = token.split(".");


      if (!header || !payload || !signature) {

        throw new Error("Invalid JWT format");

      }


      // Decode the JWT payload and header to JSON

      const decodedHeader = JSON.parse(atob(header));

      const decodedPayload = JSON.parse(atob(payload));


      // Here you would implement the logic to verify the JWT signature.

      // This example assumes a simple validation that just checks the payload.

      // Replace the following lines with your actual validation logic.


      // Ensure that JWT token hasn't expired (to test, try sending a request with an expired token "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjI0OTkyMDAwLCJleHAiOjE2MjI1MDAwMDB9.TldRGokRHJvG69SefbxIqAlQ6nnco6aLa3y7jsYXHMI")

      if (decodedPayload.exp < Math.floor(Date.now() / 1000)) {

        throw new Error("JWT has expired");

      }


      // Optionally, you could add more validation checks here (issuer, audience, etc.).

      // Also, implement actual signature validation with a custom function.


      return true;

    }


    // Execute the function to extract JWT token

    const jwtToken = getJWTToken(request);


    // If the token is not provided, serve 401 Forbidden

    if (!jwtToken) {

      return new Response("Missing JWT token", { status: 401 });

    }


    // Execute the function to validate the token

    try {

      const validToken = await validateJWT(jwtToken);

      if (validToken) {

        // If the token is valid, serve actual response

        // An example of a valid token that will expire in 2033 is "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNjI0OTkyMDAwLCJleHAiOjIwMDExMjAwMDB9._qgQ_TMrGfYgOoA8HtTZwEGoj8zAPWxsz8CT1jEAGzo"

        return fetch(request);

      } else {

        return new Response("Invalid JWT token", { status: 401 });

      }

    } catch (error) {

      return new Response("Error validating token: " + error.message, {

        status: 500,

      });

    }

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/jwt-validation/","name":"Validate JSON web tokens (JWT)"}}]}
```

---

---
title: Maintenance page
description: Serve a custom maintenance page instead of fetching content from the origin server or cache. Ideal for downtime notifications, planned maintenance, or emergency messages.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Redirects ](https://developers.cloudflare.com/search/?tags=Redirects) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/maintenance.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Maintenance page

Serve a custom maintenance page. Ideal for downtime notifications, planned maintenance, or emergency messages.

## Snippet code

JavaScript

```

// Define your customizable inputs

const statusCode = 503;

const title = "We'll Be Right Back!";

const message =

  "Our site is currently undergoing scheduled maintenance. We’re working hard to bring you a better experience. Thank you for your patience and understanding.";

const estimatedTime = "1 hour";

const contactEmail = "support@example.com";

const contactPhone = "+1 234 567 89";


export default {

  async fetch(request) {

    // Serve the maintenance page as a response

    return new Response(generateMaintenancePage(), {

      status: statusCode,

      headers: {

        "Content-Type": "text/html",

        "Retry-After": "3600", // Suggest retry after 1 hour

      },

    });

  },

};


function generateMaintenancePage() {

  return `

    <!DOCTYPE html>

    <html lang="en">

    <head>

        <meta charset="UTF-8">

        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <title>${title}</title>

        <style>

            body {

                margin: 0;

                font-family: Arial, sans-serif;

                display: flex;

                align-items: center;

                justify-content: center;

                height: 100vh;

                background-color: #f4f4f4;

                color: #333;

                text-align: center;

            }

            .container {

                max-width: 600px;

                padding: 20px;

            }

            h1 {

                font-size: 2rem;

                color: #0056b3;

                margin-bottom: 10px;

            }

            p {

                font-size: 1rem;

                margin-bottom: 20px;

                line-height: 1.5;

            }

            .contact {

                margin-top: 20px;

                font-size: 0.9rem;

                color: #666;

            }

            .contact a {

                color: #0056b3;

                text-decoration: none;

            }

            .contact a:hover {

                text-decoration: underline;

            }

            .logo {

                margin: 20px 0;

                max-width: 150px;

            }

            .timer {

                font-weight: bold;

                color: #e63946;

            }

        </style>

    </head>

    <body>

        <div class="container">

            <h1>${title}</h1>

            <p>${message}</p>

            <p>If all goes to plan, we'll be back online in <span class="timer">${estimatedTime}</span>. 🚀</p>

            <p class="contact">

                Need help? Reach out to us at <a href="mailto:${contactEmail}">${contactEmail}</a>

                or call us at <a href="tel:${contactPhone}">${contactPhone}</a>.

            </p>

        </div>

    </body>

    </html>

    `;

}


```

## Snippet rule

Configure a custom filter expression:

| Field             | Operator       | Value      |
| ----------------- | -------------- | ---------- |
| IP Source Address | is not in list | admin\_ips |

If you are using the Expression Editor, enter the following expression:

```

(not ip.src in $admin_ips)


```

The [IP list](https://developers.cloudflare.com/waf/tools/lists/custom-lists/#ip-lists) `admin_ips` was previously created and contains the list of IP addresses of the site administrators, which will be able to access the site during the maintenance period.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/maintenance/","name":"Maintenance page"}}]}
```

---

---
title: Override a Set-Cookie header with a certain value
description: Get a specific `Set-Cookie` header and update it with a certain value.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Headers ](https://developers.cloudflare.com/search/?tags=Headers)[ Cookies ](https://developers.cloudflare.com/search/?tags=Cookies)[ Response modification ](https://developers.cloudflare.com/search/?tags=Response%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/override-set-cookies-value.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Override a Set-Cookie header with a certain value

Get a specific `Set-Cookie` header and update it with a certain value.

JavaScript

```

export default {

  async fetch(request) {

    // Receive response from the origin

    const response = await fetch(request);


    // Create a new Headers object to modify response headers

    const newHeaders = new Headers(response.headers);


    // Get all Set-Cookie headers

    const cookieArray = response.headers.getSetCookie();

    if (cookieArray.length > 0) {

      const updatedCookies = cookieArray.map((cookie) => {

        // For example, replace the currency value with GBP

        if (cookie.trim().startsWith("currency=")) {

          return cookie.replace(/currency=[^;]+/, "currency=GBP");

        }

        return cookie;

      });


      // Delete the existing Set-Cookie headers

      newHeaders.delete("Set-Cookie");


      // Add the updated Set-Cookie headers individually

      updatedCookies.forEach((cookie) => {

        newHeaders.append("Set-Cookie", cookie.trim());

      });

    }


    // Return the modified response with updated headers

    return new Response(response.body, {

      status: response.status,

      headers: newHeaders,

    });

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/override-set-cookies-value/","name":"Override a Set-Cookie header with a certain value"}}]}
```

---

---
title: Redirect 403 Forbidden to a different page
description: If origin responded with `403 Forbidden` error code, redirect to different page.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Redirects ](https://developers.cloudflare.com/search/?tags=Redirects) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/redirect-forbidden-status.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Redirect 403 Forbidden to a different page

If origin responded with `403 Forbidden` error code, redirect to different page.

JavaScript

```

export default {

  async fetch(request) {

    // Send original request to the origin

    const response = await fetch(request);

    // Check if origin responded with 403 status code

    if (response.status == 403) {

      // If so, redirect to this URL

      const destinationURL = "https://example.com";

      // With this status code

      const statusCode = 301;

      // Serve redirect

      return Response.redirect(destinationURL, statusCode);

    }

    // Otherwise, serve origin's response

    else {

      return response;

    }

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/redirect-forbidden-status/","name":"Redirect 403 Forbidden to a different page"}}]}
```

---

---
title: Redirect from one domain to another
description: Redirect all requests from one domain to another domain.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Redirects ](https://developers.cloudflare.com/search/?tags=Redirects) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/redirect-replaced-domain.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Redirect from one domain to another

Redirect all requests from one domain to another domain.

JavaScript

```

export default {

  async fetch(request) {

    // Define variables to use in the response redirect.

    const base = "https://example.com";

    const statusCode = 301;


    // Clone the original URL.

    const url = new URL(request.url);


    // Define a "pathname" and "search" variables, extracting their values from the cloned URL.

    const { pathname, search } = url;


    // Define the destination URL using the variables you declared previously.

    const destinationURL = `${base}${pathname}${search}`;

    console.log(destinationURL);


    // Respond with the redirect.

    return Response.redirect(destinationURL, statusCode);

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/redirect-replaced-domain/","name":"Redirect from one domain to another"}}]}
```

---

---
title: Remove fields from API response
description: If origin responds with `JSON`, parse the response and delete fields to return a modified response.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Response modification ](https://developers.cloudflare.com/search/?tags=Response%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/remove-fields-api-response.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Remove fields from API response

If origin responds with `JSON`, parse the response and delete fields to return a modified response.

JavaScript

```

export default {

  async fetch(request) {

    // Send original request to the origin

    const response = await fetch(request);

    // Check if origin responded with JSON

    try {

      // Parse API response as JSON

      var api_response = response.json();

      // Specify the fields you want to delete. For example, to delete "botManagement" array from parsed JSON:

      delete api_response.botManagement;

      // Serve modified API response

      return Response.json(api_response);

    } catch (err) {

      // On failure, serve unmodified origin's response

      return response;

    }

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/remove-fields-api-response/","name":"Remove fields from API response"}}]}
```

---

---
title: Remove query strings before sending request to origin
description: Remove certain query strings from a request before passing to the origin.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Request modification ](https://developers.cloudflare.com/search/?tags=Request%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/remove-query-strings.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Remove query strings before sending request to origin

Remove certain query strings from a request before passing to the origin.

JavaScript

```

export default {

  async fetch(request) {

    // Define the query strings you want to remove

    const queryStringsToRemove = ["utm_source", "utm_medium", "utm_campaign"];


    // Get the URL from the request

    const url = new URL(request.url);


    // Remove the specified query strings

    queryStringsToRemove.forEach((query) => {

      url.searchParams.delete(query);

    });


    // Create a new request with the modified URL

    const modifiedRequest = new Request(url, request);


    // Pass the modified request to the origin

    const response = await fetch(modifiedRequest);


    return response;

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/remove-query-strings/","name":"Remove query strings before sending request to origin"}}]}
```

---

---
title: Remove response headers
description: Remove from response all headers that start with a certain name.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Response modification ](https://developers.cloudflare.com/search/?tags=Response%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/remove-response-headers.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Remove response headers

Remove from response all headers that start with a certain name.

JavaScript

```

export default {

  async fetch(request) {

    // Define the prefix of the headers you want to remove

    const headerPrefix = "x-header-";


    // Receive response from the origin

    const response = await fetch(request);


    // Create a new Headers object to modify response headers

    const newHeaders = new Headers(response.headers);


    // Remove headers that start with the specified prefix

    for (const [key] of newHeaders.entries()) {

      if (key.startsWith(headerPrefix)) {

        newHeaders.delete(key);

      }

    }


    // Return the modified response with updated headers

    return new Response(response.body, {

      status: response.status,

      headers: newHeaders,

    });

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/remove-response-headers/","name":"Remove response headers"}}]}
```

---

---
title: Return information about the incoming request
description: Respond with information about the incoming request provided by Cloudflare’s global network.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Logging ](https://developers.cloudflare.com/search/?tags=Logging)[ Response modification ](https://developers.cloudflare.com/search/?tags=Response%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/return-incoming-request-properties.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Return information about the incoming request

Respond with information about the incoming request provided by Cloudflare’s global network.

JavaScript

```

export default {

  async fetch(request) {

    // For any request, respond with JSON object containing all incoming request properties provided by Cloudflare network

    return Response.json(request.cf, {

      // Add new header to identify request was served by Snippets

      headers: {

        "x-snippets-hello": "Hello from Cloudflare Snippets",

      },

    });

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/return-incoming-request-properties/","name":"Return information about the incoming request"}}]}
```

---

---
title: Rewrite links on HTML pages
description: Dynamically rewrite links in HTML responses. This is useful for site migrations and branding updates.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Response modification ](https://developers.cloudflare.com/search/?tags=Response%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/rewrite-site-links.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Rewrite links on HTML pages

Dynamically rewrite links in HTML responses.

JavaScript

```

export default {

  async fetch(request) {

    // Define the old hostname here.

    const OLD_URL = "oldsite.com";

    // Then add your new hostname that should replace the old one.

    const NEW_URL = "newsite.com";


    class AttributeRewriter {

      constructor(attributeName) {

        this.attributeName = attributeName;

      }

      element(element) {

        const attribute = element.getAttribute(this.attributeName);

        if (attribute) {

          element.setAttribute(

            this.attributeName,

            attribute.replace(OLD_URL, NEW_URL),

          );

        }

      }

    }


    const rewriter = new HTMLRewriter()

      .on("a", new AttributeRewriter("href"))

      .on("img", new AttributeRewriter("src"));


    const res = await fetch(request);

    if (!res.headers.has("Content-Type")) {

      return res;

    }

    const contentType = res.headers.get("Content-Type");

    if (typeof contentType !== "string") {

      return res;

    }


    // If the response is HTML, it can be transformed with

    // HTMLRewriter -- otherwise, it should pass through

    if (contentType.startsWith("text/html")) {

      return rewriter.transform(res);

    } else {

      return res;

    }

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/rewrite-site-links/","name":"Rewrite links on HTML pages"}}]}
```

---

---
title: Change origin and modify paths
description: Route requests to a different origin, prepend a directory to the URL path, and remove specific segments.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ URL rewrite ](https://developers.cloudflare.com/search/?tags=URL%20rewrite) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/route-and-rewrite.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Change origin and modify paths

Reroute a request to a different origin and modify the URL path.

This example demonstrates how to use Cloudflare Snippets to:

* Reroute incoming requests to a different origin.
* Prepend a directory to the URL path.
* Remove specific segments from the URL path.

JavaScript

```

export default {

  async fetch(request) {

    // Clone the original request to create a new request object

    const newRequest = new Request(request);


    // Add a header to identify a rerouted request at the new origin

    newRequest.headers.set("X-Rerouted", "1");


    // Clone and parse the original URL

    const url = new URL(request.url);


    // Step 1: Reroute to a different origin

    url.hostname = "example.com"; // Change the hostname to the new origin


    // Step 2: Append a directory to the path

    url.pathname = `/new-path${url.pathname}`; // Prepend "/new-path" to the current path


    // Step 3: Remove a specific segment from the path

    url.pathname = url.pathname.replace("/remove-me", ""); // Rewrite `/remove-me/something` to `/something`


    // Fetch the modified request from the updated URL

    return await fetch(url, newRequest);

  },

};


```

This configuration will perform the following rewrites:

| Request URL                       | URL after rewrite                |
| --------------------------------- | -------------------------------- |
| https://subdomain.example.com/foo | https://example.com/new-path/foo |
| https://example.com/remove-me/bar | https://example.com/new-path/bar |
| https://example.net/remove-me     | https://example.com/new-path     |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/route-and-rewrite/","name":"Change origin and modify paths"}}]}
```

---

---
title: Set security headers
description: Set common security headers such as X-XSS-Protection, X-Frame-Options, and X-Content-Type-Options.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Headers ](https://developers.cloudflare.com/search/?tags=Headers)[ Response modification ](https://developers.cloudflare.com/search/?tags=Response%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/security-headers.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Set security headers

Set common security headers such as X-XSS-Protection, X-Frame-Options, and X-Content-Type-Options.

JavaScript

```

export default {

  async fetch(request) {

    // Define an object with the security headers you want to set.

    // Refer to https://developers.cloudflare.com/rules/snippets/examples/security-headers/#other-common-security-headers for more options.

    const DEFAULT_SECURITY_HEADERS = {

      "X-Content-Type-Options": "nosniff",

      "Referrer-Policy": "strict-origin-when-cross-origin",

      "Cross-Origin-Embedder-Policy": 'require-corp; report-to="default";',

      "Cross-Origin-Opener-Policy": 'same-site; report-to="default";',

      "Cross-Origin-Resource-Policy": "same-site",

    };


    // You can also define headers to be deleted.

    const BLOCKED_HEADERS = [

      "Public-Key-Pins",

      "X-Powered-By",

      "X-AspNet-Version",

    ];


    // Receive response from the origin.

    let response = await fetch(request);


    // Create a new Headers object to modify response headers

    let newHeaders = new Headers(response.headers);


    // This sets the headers for HTML responses:

    if (

      newHeaders.has("Content-Type") &&

      !newHeaders.get("Content-Type").includes("text/html")

    ) {

      return new Response(response.body, {

        status: response.status,

        statusText: response.statusText,

        headers: newHeaders,

      });

    }


    // Use DEFAULT_SECURITY_HEADERS object defined above to set the new security headers.

    Object.keys(DEFAULT_SECURITY_HEADERS).map((name) => {

      newHeaders.set(name, DEFAULT_SECURITY_HEADERS[name]);

    });


    // Use the BLOCKED_HEADERS object defined above to delete headers you wish to block.

    BLOCKED_HEADERS.forEach((name) => {

      newHeaders.delete(name);

    });


    return new Response(response.body, {

      status: response.status,

      statusText: response.statusText,

      headers: newHeaders,

    });

  },

};


```

## Other common security headers

* Content-Security-Policy headers: Enabling these headers will permit content from a trusted domain and all its subdomains. Refer to [Content-Security-Policy ↗](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy) for details.

JavaScript

```

"Content-Security-Policy": "default-src 'self' example.com *.example.com",


```

* Strict-Transport-Security headers: These are not automatically set because your website might get added to Chrome's HSTS preload list.

JavaScript

```

"Strict-Transport-Security" : "max-age=63072000; includeSubDomains; preload",


```

* Permissions-Policy header: Allow or deny the use of browser features, such as opting out of FLoC.

JavaScript

```

"Permissions-Policy": "interest-cohort=()",


```

* X-XSS-Protection header: Prevents a page from loading if an XSS attack is detected. Refer to [X-XSS-Protection ↗](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-XSS-Protection) for details.

JavaScript

```

"X-XSS-Protection": "0",


```

* X-Frame-Options header: Prevents click-jacking attacks. Refer to [X-Frame-Options ↗](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Frame-Options).

JavaScript

```

"X-Frame-Options": "DENY",


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/security-headers/","name":"Set security headers"}}]}
```

---

---
title: Send timestamp to origin as a custom header
description: Convert timestamp to hexadecimal format and send it as a custom header to the origin.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Headers ](https://developers.cloudflare.com/search/?tags=Headers)[ Request modification ](https://developers.cloudflare.com/search/?tags=Request%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/send-timestamp-to-origin.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Send timestamp to origin as a custom header

Convert timestamp to hexadecimal format and send it as a custom header to the origin.

JavaScript

```

export default {

  async fetch(request) {

    // Get the current timestamp

    const timestamp = Date.now();


    // Convert the timestamp to hexadecimal format

    const hexTimestamp = timestamp.toString(16);


    // Clone the request and add the custom header

    const modifiedRequest = new Request(request, {

      headers: new Headers(request.headers),

    });

    modifiedRequest.headers.set("X-Hex-Timestamp", hexTimestamp);


    // Log the custom header for debugging

    console.log(`X-Hex-Timestamp: ${hexTimestamp}`);


    // Pass the modified request to the origin

    const response = await fetch(modifiedRequest);


    return response;

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/send-timestamp-to-origin/","name":"Send timestamp to origin as a custom header"}}]}
```

---

---
title: Route to a different origin based on origin response
description: If response to the original request is not `200 OK` or a redirect, send to another origin.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Redirects ](https://developers.cloudflare.com/search/?tags=Redirects) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/serve-different-origin.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Route to a different origin based on origin response

If response to the original request is not `200 OK` or a redirect, send to another origin.

JavaScript

```

export default {

  async fetch(request) {

    // Send original request to the origin

    const response = await fetch(request);


    // If response is not 200 OK or a redirect, send to another origin

    if (!response.ok && !response.redirected) {

      // First, clone the original request to construct a new request

      const newRequest = new Request(request);

      // Add a header to identify a re-routed request at the new origin

      newRequest.headers.set("X-Rerouted", "1");

      // Clone the original URL

      const url = new URL(request.url);

      // Send request to a different origin / hostname

      url.hostname = "example.com";

      // Serve response to the new request from the origin

      return await fetch(url, newRequest);

    }


    // If response is 200 OK or a redirect, serve it

    return response;

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/serve-different-origin/","name":"Route to a different origin based on origin response"}}]}
```

---

---
title: Sign requests
description: Verify a signed request using the HMAC and SHA-256 algorithms or return a 403.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Authentication ](https://developers.cloudflare.com/search/?tags=Authentication)[ Request modification ](https://developers.cloudflare.com/search/?tags=Request%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/signing-requests.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Sign requests

Verify a signed request using the HMAC and SHA-256 algorithms or return a 403.

The following Snippet will:

* For request URLs beginning with `/generate/`, replace `/generate/` with `/`, sign the resulting path with its timestamp, and return the full, signed URL in the response body.
* For all other request URLs, verify the signed URL and allow the request through.

JavaScript

```

export default {

  async fetch(request) {

    const secretKey = "your_secret_key"; // Replace with your actual secret key

    const expiration = 60; // Expiration time in seconds (how long an HMAC token should be valid for)


    const encoder = new TextEncoder();


    // Import the secret key for HMAC-SHA256 signing

    const key = await crypto.subtle.importKey(

      "raw",

      encoder.encode(secretKey),

      { name: "HMAC", hash: "SHA-256" },

      false,

      ["sign", "verify"],

    );


    const url = new URL(request.url);


    // Check if the request URL starts with /generate/

    if (url.pathname.startsWith("/generate/")) {

      // Replace /generate/ with /

      url.pathname = url.pathname.replace("/generate/", "/");


      const currentTimestamp = Math.floor(Date.now() / 1000); // Current timestamp in seconds


      // Data to authenticate: combine pathname and timestamp

      const dataToAuthenticate = `${url.pathname}${currentTimestamp}`;


      // Sign the data with HMAC-SHA256

      const signature = await crypto.subtle.sign(

        "HMAC",

        key,

        encoder.encode(dataToAuthenticate),

      );


      // Encode the timestamp and HMAC in a secure manner

      const signatureBase64 = btoa(

        String.fromCharCode(...new Uint8Array(signature)),

      );

      const signedData = `${currentTimestamp}-${signatureBase64}`;

      const encodedSignedData = encodeURIComponent(signedData);


      // Create the signed URL

      const signedURL = `${url}?verify=${encodedSignedData}`;


      // Return the signed URL in the response body

      return new Response(signedURL, { status: 200 });

    }


    // For all other request URLs, verify the signed URL

    const params = new URLSearchParams(url.search);

    const verifyParam = params.get("verify");


    if (!verifyParam) {

      return new Response("Verification parameter is missing", { status: 403 });

    }


    // Decode and split the verify parameter into timestamp and HMAC

    const decodedVerifyParam = decodeURIComponent(verifyParam);

    const [timestampStr, receivedMac] = decodedVerifyParam.split("-");


    // Parse timestamp and ensure it's a valid number

    const timestamp = parseInt(timestampStr, 10);

    if (isNaN(timestamp)) {

      return new Response("Invalid timestamp", { status: 403 });

    }


    // Check if the request has expired

    const currentTimestamp = Math.floor(Date.now() / 1000);

    if (currentTimestamp > timestamp + expiration) {

      return new Response("Signed URL has expired", { status: 403 });

    }


    // Remove the verify parameter to verify the URL

    params.delete("verify");

    url.search = params.toString();


    // Construct the data to authenticate for verification

    const dataToVerify = `${url.pathname}${timestamp}`;


    // Verify the signature with HMAC-SHA256

    const isValid = await crypto.subtle.verify(

      "HMAC",

      key,

      new Uint8Array([...atob(receivedMac)].map((char) => char.charCodeAt(0))),

      encoder.encode(dataToVerify),

    );


    if (!isValid) {

      return new Response("Invalid signature", { status: 403 });

    }


    // Continue processing the request if the signature is valid

    return fetch(request);

  },

};


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/signing-requests/","name":"Sign requests"}}]}
```

---

---
title: Slow down suspicious requests
description: Define a delay to be used when incoming requests match a rule you consider suspicious based on the bot score.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Request modification ](https://developers.cloudflare.com/search/?tags=Request%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/examples/slow-suspicious-requests.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Slow down suspicious requests

Define a delay to be used when incoming requests match a rule you consider suspicious based on the bot score.

## Snippet code

JavaScript

```

export default {

  async fetch(request) {

    // Define delay

    const delay_in_seconds = 5;

    // Introduce a delay

    await new Promise((resolve) =>

      setTimeout(resolve, delay_in_seconds * 1000),

    ); // Set delay in milliseconds


    // Pass the request to the origin

    const response = await fetch(request);

    return response;

  },

};


```

## Snippet rule

Configure a custom filter expression:

| Field     | Operator  | Value |
| --------- | --------- | ----- |
| Bot Score | less than | 10    |

If you are using the Expression Editor, enter the following expression:

```

(cf.bot_management.score lt 10)


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/examples/","name":"Snippets examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/snippets/examples/slow-suspicious-requests/","name":"Slow down suspicious requests"}}]}
```

---

---
title: How Snippets work
description: Cloudflare Snippets are executed based on rules defined within your zone. Here is how the process works:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/how-it-works.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# How Snippets work

Cloudflare Snippets are executed based on rules defined within your zone. Here is how the process works:

![Diagram of the snippets execution workflow](https://developers.cloudflare.com/_astro/snippets-execution.Cb6ZLHBP_Z1QQkWy.webp) 

## 1\. Evaluate snippet rules

For each incoming request, Cloudflare evaluates the expression of every snippet rule defined in the zone. The evaluation checks for a match based on various request properties (such as bot score, WAF attack score, country of origin, and cookies).

## 2\. Build Snippets table

For every snippet rule in a zone that matches an incoming request, Cloudflare adds the corresponding unique snippet ID to a Snippets table.

## 3\. Execute snippets code

Once all the rules have been evaluated and the full table has been compiled, the Snippets Internal Worker Service starts processing all the information in the table.

This Worker receives all the snippet IDs stored in the table that are to be sequentially executed. Each snippet receives the modified request from the previous snippet and applies new modifications to it.

## 4\. Continue with the request execution workflow

After executing the final snippet IDs, the resulting modified request is passed back to the request execution workflow. Refer to [Execution order](https://developers.cloudflare.com/rules/snippets/#execution-order) for more information on the Rules features evaluated before and after Cloudflare Snippets.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/how-it-works/","name":"How Snippets work"}}]}
```

---

---
title: When to use Snippets vs Workers
description: This guide helps you determine when to use Snippets or Workers on Cloudflare's global network.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/snippets/when-to-use.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# When to use Snippets vs Workers

This guide helps you determine when to use Snippets or Workers on Cloudflare's global network. It provides best practices, comparisons, and real-world use cases to help you choose the right product for your workload.

## What are Snippets?

Cloudflare Snippets provide a fast, declarative way to modify HTTP requests and responses at the edge — without requiring a full-stack compute platform. Snippets extend [Cloudflare Rules](https://developers.cloudflare.com/rules/) by allowing you to write JavaScript-based logic that modifies requests before they reach an origin and responses after they return from upstream.

Snippets enable you to:

* Modify headers, validate JWTs, and implement complex rewrites or redirects.
* Retry failed requests to different origins and apply custom caching strategies.
* Execute multiple Snippets sequentially, with each Snippet modifying the request or response before handing it off to the next.

Snippets are included at no additional cost in [all paid plans](https://developers.cloudflare.com/rules/snippets/#availability), making them the preferred solution for lightweight edge logic.

## What are Workers?

By contrast, [Cloudflare Workers](https://developers.cloudflare.com/workers/) provide a full-stack compute platform designed for applications requiring state, compute, and integrations with Cloudflare’s [Developer Platform](https://developers.cloudflare.com/learning-paths/workers/devplat/intro-to-devplat/). Workers operate on a [usage-based pricing model](https://developers.cloudflare.com/workers/platform/pricing/) and include a free tier.

---

## Choosing the right product

Snippets are ideal for fast, cost-free request and response modifications at the edge. They extend [Cloudflare Rules](https://developers.cloudflare.com/rules/) without requiring additional infrastructure or external solutions.

### When to use Snippets

* Ultra-fast traffic modifications applied directly on Cloudflare's network.
* Extend Cloudflare Rules beyond built-in actions for greater control.
* Simplify CDN migrations by replacing VCL, EdgeWorkers, or on-premise logic.
* Modify headers, cache responses, and perform redirects.
* Integrate edge logic into development workflows using JavaScript.

### What Snippets are not designed for

* Persistent state management (for example, session storage or databases).
* Compute-intensive tasks (for example, image transformations or [AI inference](https://developers.cloudflare.com/workers-ai/)).
* Deep integrations with [Developer Platform](https://developers.cloudflare.com/learning-paths/workers/devplat/intro-to-devplat/) services like [Durable Objects](https://developers.cloudflare.com/durable-objects/) or [D1](https://developers.cloudflare.com/d1/).
* Use cases requiring advanced runtime features, such as:  
   * [Environment variables](https://developers.cloudflare.com/workers/configuration/environment-variables/)  
   * [Observability](https://developers.cloudflare.com/workers/observability/logs/)  
   * [Bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/)  
   * [Cron triggers](https://developers.cloudflare.com/workers/configuration/cron-triggers/)  
   * High [compute limits](https://developers.cloudflare.com/rules/snippets/#limits)

### Key features

* Ultra-fast, edge-optimized execution, powered by [Ruleset Engine](https://developers.cloudflare.com/ruleset-engine/) and [Workers runtime](https://developers.cloudflare.com/workers/runtime-apis/).
* Included at no additional cost on [all paid plans](https://developers.cloudflare.com/rules/snippets/#availability).
* Granular request matching using dozens of request attributes, such as [URI](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.request.full%5Furi/), [user-agent](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.user%5Fagent/), and [cookies](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.request.cookies/).
* Sequential execution – multiple Snippets [can run](https://developers.cloudflare.com/rules/snippets/how-it-works/) on the same request, applying modifications step by step.
* Native integration with [Cloudflare Rules](https://developers.cloudflare.com/rules/) – Snippets inherit request modifications from other products running in earlier [request phases](https://developers.cloudflare.com/ruleset-engine/reference/phases-list/#request-phases).
* JavaScript and Web APIs support, including:  
   * [Fetch API](https://developers.cloudflare.com/workers/runtime-apis/fetch/)  
   * [Cache API](https://developers.cloudflare.com/workers/runtime-apis/cache/)
* Essential [Workers runtime](https://developers.cloudflare.com/workers/runtime-apis/) features, such as:  
   * [request.cf object](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties)  
   * [HTMLRewriter](https://developers.cloudflare.com/workers/runtime-apis/html-rewriter/)
* Automated deployment and versioning via [Terraform](https://developers.cloudflare.com/rules/snippets/create-terraform/).

---

## Snippets vs Workers: Feature comparison

| Feature                                                                                                                                                                                                                                                                                                          | Snippets | Workers |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------- |
| Execute scripts based on request attributes (for example, headers, geolocation, and cookies)                                                                                                                                                                                                                     | ✅        | ❌       |
| Execute code on a specific URL route                                                                                                                                                                                                                                                                             | ✅        | ✅       |
| Modify HTTP requests/responses or serve a [different response](https://developers.cloudflare.com/rules/snippets/examples/maintenance/)                                                                                                                                                                           | ✅        | ✅       |
| [Add](https://developers.cloudflare.com/rules/snippets/examples/hex-timestamp/), [remove](https://developers.cloudflare.com/rules/snippets/examples/remove-response-headers/), or [rewrite](https://developers.cloudflare.com/rules/snippets/examples/override-set-cookies-value/) headers dynamically           | ✅        | ✅       |
| [Cache](https://developers.cloudflare.com/rules/snippets/examples/custom-cache/) assets at the edge                                                                                                                                                                                                              | ✅        | ✅       |
| Route traffic dynamically between [origin servers](https://developers.cloudflare.com/rules/snippets/examples/serve-different-origin/)                                                                                                                                                                            | ✅        | ✅       |
| [Authenticate](https://developers.cloudflare.com/rules/snippets/examples/auth-with-headers/) requests, [pre-sign](https://developers.cloudflare.com/cache/interaction-cloudflare-products/waf-snippets/) URLs, run [A/B testing](https://developers.cloudflare.com/rules/snippets/examples/ab-testing-same-url/) | ✅        | ✅       |
| Define logic using [JavaScript and Web APIs](https://developers.cloudflare.com/workers/languages/javascript/)                                                                                                                                                                                                    | ✅        | ✅       |
| Perform compute-heavy tasks (for example, [AI](https://developers.cloudflare.com/workers-ai/), [image transformations](https://developers.cloudflare.com/images/transform-images/transform-via-workers/))                                                                                                        | ❌        | ✅       |
| Store persistent data (for example, [KV](https://developers.cloudflare.com/kv/), [Durable Objects](https://developers.cloudflare.com/durable-objects/), and [D1](https://developers.cloudflare.com/d1/))                                                                                                         | ❌        | ✅       |
| Build [APIs](https://developers.cloudflare.com/d1/tutorials/build-a-comments-api/) and [full-stack applications](https://developers.cloudflare.com/pages/framework-guides/deploy-an-astro-site/#video-tutorial)                                                                                                  | ❌        | ✅       |
| Use TypeScript, Python, Rust, or other programming [languages](https://developers.cloudflare.com/workers/languages/)                                                                                                                                                                                             | ❌        | ✅       |
| Support non-HTTP [protocols](https://developers.cloudflare.com/workers/reference/protocols/)                                                                                                                                                                                                                     | ❌        | ✅       |
| Analyze execution [logs](https://developers.cloudflare.com/workers/observability/logs/workers-logs/) and track performance metrics                                                                                                                                                                               | ❌        | ✅       |
| Deploy via [command-line interface (CLI)](https://developers.cloudflare.com/workers/wrangler/)                                                                                                                                                                                                                   | ❌        | ✅       |
| Roll out gradually, roll back to previous [versions](https://developers.cloudflare.com/workers/configuration/versions-and-deployments/)                                                                                                                                                                          | ❌        | ✅       |
| Optimize execution with [Smart Placement](https://developers.cloudflare.com/workers/configuration/placement/)                                                                                                                                                                                                    | ❌        | ✅       |

---

## Code examples: Common Snippets templates

Below are practical use cases demonstrating Snippets in action. You can find more templates to get started in the [Examples](https://developers.cloudflare.com/rules/snippets/examples/) section.

### Modify HTTP headers

Modifies request and response headers dynamically.

JavaScript

```

export default {

  async fetch(request) {

    // Get the current timestamp

    const timestamp = Date.now();


    // Convert the timestamp to hexadecimal format

    const hexTimestamp = timestamp.toString(16);


    // Clone the request and add the custom header with HEX timestamp

    const modifiedRequest = new Request(request, {

      headers: new Headers(request.headers),

    });

    modifiedRequest.headers.set("X-Hex-Timestamp", hexTimestamp);


    // Pass the modified request to the origin

    const response = await fetch(modifiedRequest);


    // Clone the response so that it's no longer immutable

    const newResponse = new Response(response.body, response);


    // Add a custom header with a value to the response

    newResponse.headers.append(

      "x-snippets-hello",

      "Hello from Cloudflare Snippets",

    );


    // Delete headers from the response

    newResponse.headers.delete("x-header-to-delete");

    newResponse.headers.delete("x-header2-to-delete");


    // Adjust the value for an existing header in the response

    newResponse.headers.set("x-header-to-change", "NewValue");


    // Serve modified response to the visitor

    return newResponse;

  },

};


```

### Serve a custom maintenance page

Routes traffic to a maintenance page when your origin is undergoing a planned maintenance.

JavaScript

```

export default {

  async fetch(request) {

    return new Response(

      `

            <!DOCTYPE html>

            <html lang="en">

            <head>

                <meta charset="UTF-8">

                <title>We'll Be Right Back!</title>

                <style> body { font-family: Arial, sans-serif; text-align: center; padding: 20px; } </style>

            </head>

            <body>

                <h1>We'll Be Right Back!</h1>

                <p>Our site is undergoing maintenance. Check back soon!</p>

            </body>

            </html>

        `,

      { status: 503, headers: { "Content-Type": "text/html" } },

    );

  },

};


```

### Custom cache

Performs programmatic caching at the edge to reduce origin load.

JavaScript

```

const CACHE_DURATION = 30 * 24 * 60 * 60; // 30 days


export default {

  async fetch(request) {

    const cache = caches.default;

    const cacheKey = new Request(request.url, { method: "GET" });


    let response = await cache.match(cacheKey);

    if (!response) {

      response = await fetch(request);

      response = new Response(response.body, response);

      response.headers.set("Cache-Control", `s-maxage=${CACHE_DURATION}`);

      await cache.put(cacheKey, response.clone());

    }

    return response;

  },

};


```

### Redirect based on country code

Redirects visitors based on their geographic location.

JavaScript

```

export default {

  async fetch(request) {

    const country = request.cf.country;

    const redirectMap = {

      US: "https://example.com/us",

      EU: "https://example.com/eu",

    };

    if (redirectMap[country])

      return Response.redirect(redirectMap[country], 301);

    return fetch(request);

  },

};


```

### Redirect 403 Forbidden to a different page

If the origin responded with `403 Forbidden` error code, redirects visitor to a different page.

JavaScript

```

export default {

  async fetch(request) {

    // Send original request to the origin

    const response = await fetch(request);

    // Check if origin responded with 403 status code

    if (response.status == 403) {

      // If so, redirect to this URL

      const destinationURL = "https://example.com";

      // With this status code

      const statusCode = 301;

      // Serve redirect

      return Response.redirect(destinationURL, statusCode);

    }

    // Otherwise, serve origin's response

    else {

      return response;

    }

  },

};


```

### Retry to another origin

If the response to the original request is not `200 OK` or a redirect, sends to another origin.

JavaScript

```

export default {

  async fetch(request) {

    // Send original request to the origin

    const response = await fetch(request);


    // If response is not 200 OK or a redirect, send to another origin

    if (!response.ok && !response.redirected) {

      // First, clone the original request to construct a new request

      const newRequest = new Request(request);

      // Add a header to identify a re-routed request at the new origin

      newRequest.headers.set("X-Rerouted", "1");

      // Clone the original URL

      const url = new URL(request.url);

      // Send request to a different origin / hostname

      url.hostname = "example.com";

      // Serve response to the new request from the origin

      return await fetch(url, newRequest);

    }


    // If response is 200 OK or a redirect, serve it

    return response;

  },

};


```

### Remove fields from API response

If the origin responds with JSON, deletes sensitive fields before returning a response to the visitor.

JavaScript

```

export default {

  async fetch(request) {

    // Send original request to the origin

    const response = await fetch(request);

    // Check if origin responded with JSON

    try {

      // Parse API response as JSON

      var api_response = response.json();

      // Specify the fields you want to delete. For example, to delete "botManagement" array from parsed JSON:

      delete api_response.botManagement;

      // Serve modified API response

      return Response.json(api_response);

    } catch (err) {

      // On failure, serve unmodified origin's response

      return response;

    }

  },

};


```

### Set CORS headers

Adjusts [Cross-Origin Resource Sharing (CORS) ↗](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) headers and handles preflight requests.

JavaScript

```

// Define CORS headers

const corsHeaders = {

  "Access-Control-Allow-Origin": "*", // Replace * with your allowed origin(s)

  "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS", // Adjust allowed methods as needed

  "Access-Control-Allow-Headers": "Content-Type, Authorization", // Adjust allowed headers as needed

  "Access-Control-Max-Age": "86400", // Adjust max age (in seconds) as needed

};


export default {

  async fetch(request) {

    // Make a copy of the request to modify its headers

    const modifiedRequest = new Request(request);


    // Handle preflight requests (OPTIONS)

    if (request.method === "OPTIONS") {

      return new Response(null, {

        headers: {

          ...corsHeaders,

        },

        status: 200, // Respond with OK status for preflight requests

      });

    }


    // Pass the modified request through to the origin

    const response = await fetch(modifiedRequest);


    // Make a copy of the response to modify its headers

    const modifiedResponse = new Response(response.body, response);


    // Set CORS headers on the response

    Object.keys(corsHeaders).forEach((header) => {

      modifiedResponse.headers.set(header, corsHeaders[header]);

    });


    return modifiedResponse;

  },

};


```

### Rewrite links on HTML pages

Replaces outdated links without having to make changes on your origin.

JavaScript

```

export default {

  async fetch(request) {

    // Define the old hostname here.

    const OLD_URL = "oldsite.com";

    // Then add your new hostname that should replace the old one.

    const NEW_URL = "newsite.com";


    class AttributeRewriter {

      constructor(attributeName) {

        this.attributeName = attributeName;

      }

      element(element) {

        const attribute = element.getAttribute(this.attributeName);

        if (attribute) {

          element.setAttribute(

            this.attributeName,

            attribute.replace(OLD_URL, NEW_URL),

          );

        }

      }

    }


    const rewriter = new HTMLRewriter()

      .on("a", new AttributeRewriter("href"))

      .on("img", new AttributeRewriter("src"));


    const res = await fetch(request);

    const contentType = res.headers.get("Content-Type");


    // If the response is HTML, it can be transformed with

    // HTMLRewriter -- otherwise, it should pass through

    if (contentType.startsWith("text/html")) {

      return rewriter.transform(res);

    } else {

      return res;

    }

  },

};


```

### Slow down requests

Defines a delay to be used when incoming requests match your rule. Useful for suspicious requests.

JavaScript

```

export default {

  async fetch(request) {

    // Define delay

    const delay_in_seconds = 5;

    // Introduce a delay

    await new Promise((resolve) =>

      setTimeout(resolve, delay_in_seconds * 1000),

    ); // Set delay in milliseconds


    // Pass the request to the origin

    const response = await fetch(request);

    return response;

  },

};


```

---

## Using Snippets and Workers together

While Snippets and Workers have distinct capabilities, they can work together to handle complex traffic workflows.

To avoid conflicts, Snippets and Workers should operate on separate request paths rather than running on the same URL. Have them fetch their respective URLs as a subrequest within their logic, ensuring smooth execution and caching behavior.

### Example 1: Passing data between Snippets and Workers

Snippets can modify incoming requests before they reach a Worker, and Workers can read these modifications, perform additional transformations, and pass them downstream.

#### Snippet: Add a custom header

JavaScript

```

export default {

  async fetch(request) {

    // Get the current timestamp

    const timestamp = Date.now();

    const hexTimestamp = timestamp.toString(16);


    // Clone request and add a custom header

    const modifiedRequest = new Request(request, {

      headers: new Headers(request.headers),

    });

    modifiedRequest.headers.set("X-Hex-Timestamp", hexTimestamp);


    console.log(`X-Hex-Timestamp: ${hexTimestamp}`);


    // Pass modified request to origin

    return fetch(modifiedRequest);

  },

};


```

#### Worker: Read a header and add it to the response

JavaScript

```

export default {

  async fetch(request) {

    const response = await fetch("https://{snippets_url}", request); // Ensure {snippets_url} points to the endpoint modified by Snippets

    const newResponse = new Response(response.body, response);


    let hexTimestamp = request.headers.get("X-Hex-Timestamp") || "null";

    console.log(hexTimestamp);


    newResponse.headers.set("X-Hex-Timestamp", hexTimestamp);

    return newResponse;

  },

};


```

**Result:** The Snippet sets `X-Hex-Timestamp`, which the Worker reads and forwards to the origin.

### Example 2: Caching Worker responses using Snippets

A Worker performs compute-heavy processing (for example, image transformation), while a Snippet serves cached results to avoid unnecessary Worker execution. This can be helpful in situations when running Workers [before cache](https://developers.cloudflare.com/cache/interaction-cloudflare-products/workers/) is not desirable.

#### Worker: Transform and cache responses

JavaScript

```

export default {

  async fetch(request) {

    const url = new URL(request.url);

    url.hostname = "origin.example.com"; // Ensure this hostname points to the origin where the resource is hosted


    const newRequest = new Request(url, request);

    const customKey = `https://${url.hostname}${url.pathname}`; // This custom cache key should be the same in both Worker and Snippet configuration for cache to work


    // Fetch and modify response

    const response = await fetch(newRequest);

    const newResponse = new Response(response.body, response);


    // Cache the transformed response

    const cache = caches.default;

    const cachedResponse = newResponse.clone();

    cachedResponse.headers.set("X-Cached-In-Workers", "true");

    await cache.put(customKey, cachedResponse);


    newResponse.headers.set("X-Retrieved-From-Workers", "true");

    return newResponse;

  },

};


```

#### Snippet: Serve cached responses or forward to Worker

JavaScript

```

export default {

  async fetch(request) {

    const url = new URL(request.url);

    url.hostname = "origin.example.com"; // Ensure this hostname points to the origin where the resource is hosted

    const cacheKey = `https://${url.hostname}${url.pathname}`; // This custom cache key should be the same in both Worker and Snippet configuration for cache to work


    // Access cache

    const cache = caches.default;

    let response = await cache.match(cacheKey);


    if (!response) {

      console.log(`Cache miss for: ${cacheKey}. Fetching from Worker...`);

      url.hostname = "worker.example.com"; // Ensure this hostname points to the Workers route

      response = await fetch(new Request(url, request));


      // Cache the response for future use

      response = new Response(response.body, response);

      response.headers.set("Cache-Control", `s-maxage=3600`);

      response.headers.set("x-snippets-cache", "stored");

    } else {

      console.log(`Cache hit for: ${cacheKey}`);

      response = new Response(response.body, response);

      response.headers.set("x-snippets-cache", "hit");

    }


    return response;

  },

};


```

**Result:** The transformed response (`X-Cached-In-Workers: true`) is served from cache, avoiding redundant Worker execution (`X-Retrieved-From-Workers` is not present). When cache expires, the Snippet fetches a fresh version.

---

## Migration between Snippets and Workers

Snippets and Workers share the same [Workers runtime](https://developers.cloudflare.com/workers/runtime-apis/), meaning JavaScript code that does not rely on bindings, persistent storage, or advanced execution features can be migrated seamlessly between them.

### When to migrate workloads to Snippets

You should consider migrating a Worker to Snippets if it:

* Only modifies headers, redirects, caching rules, or origin routing.
* Does not require bindings, persistent storage, or external integrations.
* Is a lightweight JavaScript function with simple logic.
* Needs to run an unlimited number of times for free on a Pro, Business, or Enterprise plan.

Migrating to Snippets allows you to:

* Leverage advanced request matching via the [Ruleset Engine](https://developers.cloudflare.com/ruleset-engine/).
* Eliminate usage-based billing — Snippets are [included at no cost](https://developers.cloudflare.com/rules/snippets/#availability) on all paid plans.
* Simplify management by integrating traffic modifications directly into Cloudflare Rules.

### When to migrate workloads to Workers

You should migrate from Snippets to Workers if your logic:

* Exceeds execution time, memory, or other [limits](https://developers.cloudflare.com/rules/snippets/#limits).
* Requires persistent state management, such as:  
   * [Key-Value (KV) storage](https://developers.cloudflare.com/kv/)  
   * [SQL databases (D1)](https://developers.cloudflare.com/d1/)  
   * [Durable Objects](https://developers.cloudflare.com/durable-objects/)
* Performs compute-intensive operations, including:  
   * [AI inference](https://developers.cloudflare.com/workers-ai/)  
   * [Vector search](https://developers.cloudflare.com/vectorize/)  
   * [Image transformations](https://developers.cloudflare.com/images/transform-images/transform-via-workers/)
* Interacts with Cloudflare's [Developer Platform](https://developers.cloudflare.com/learning-paths/workers/devplat/intro-to-devplat/).
* Requires [unit testing](https://developers.cloudflare.com/workers/testing/).
* Needs deployment automation via CLI ([Wrangler](https://developers.cloudflare.com/workers/wrangler/)).

If your Snippet reaches the limits of execution time, memory, or functionality, transitioning to Workers ensures your logic can scale without restrictions.

---

## Conclusion

Cloudflare Snippets provide a production-ready solution for fast, declarative edge traffic logic, bridging the gap between [Cloudflare Rules](https://developers.cloudflare.com/rules/) and [Developer Platform](https://developers.cloudflare.com/learning-paths/workers/devplat/intro-to-devplat/).

Snippets and Workers solve different problems:

* Use Snippets for fast, lightweight traffic modifications at the edge, including header rewrites, caching, redirects, origin routing, custom responses, A/B testing and authentication.
* Workers are built for advanced compute, persistent state, and full-stack applications.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/snippets/","name":"Cloudflare Snippets"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/snippets/when-to-use/","name":"When to use Snippets vs Workers"}}]}
```

---

---
title: Transform Rules
description: Transform Rules allow you to adjust the URI path, query string, and HTTP headers of requests and responses on the Cloudflare global network.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Transform Rules

Transform Rules allow you to adjust the URI path, query string, and HTTP headers of requests and responses on the Cloudflare global network.

There are several types of Transform Rules:

* [**URL Rewrite Rules**](https://developers.cloudflare.com/rules/transform/url-rewrite/): Rewrite the URL path and query string of an HTTP request.
* [**Request Header Transform Rules**](https://developers.cloudflare.com/rules/transform/request-header-modification/): Set the value of an HTTP request header or remove a request header.
* [**Response Header Transform Rules**](https://developers.cloudflare.com/rules/transform/response-header-modification/): Set the value of an HTTP response header or remove a response header.
* [**Managed Transforms**](https://developers.cloudflare.com/rules/transform/managed-transforms/): Perform common adjustments to HTTP request and response headers with the click of a button.

For more complex header modifications and rewrite logic, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

  
Note

Transform Rules require that you [proxy the DNS records](https://developers.cloudflare.com/dns/proxy-status/) of your domain (or subdomain) through Cloudflare.

## Get started

Cloudflare provides you with rules templates for common use cases.

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Templates**, and then select one of the available templates.

You can also refer to the [Examples gallery](https://developers.cloudflare.com/rules/examples/) in the developer docs.

Alternatively, create a transform rule from scratch in the dashboard or via Cloudflare API. Refer to the following sections for detailed instructions:

* [URL Rewrite Rules](https://developers.cloudflare.com/rules/transform/url-rewrite/)
* [Request Header Transform Rules](https://developers.cloudflare.com/rules/transform/request-header-modification/)
* [Response Header Transform Rules](https://developers.cloudflare.com/rules/transform/response-header-modification/)
* [Managed Transforms](https://developers.cloudflare.com/rules/transform/managed-transforms/)

For Terraform examples, refer to [Transform Rules configuration using Terraform](https://developers.cloudflare.com/terraform/additional-configurations/transform-rules/).

Refer to [Rules language](https://developers.cloudflare.com/ruleset-engine/rules-language/) for more information on building expressions for Transform Rules.

## Availability

Cloudflare Transform Rules are available to all customers. Support for regular expressions depends on your Cloudflare plan.

This table outlines the Transform Rules features available with each customer plan:

| Free                   | Pro | Business | Enterprise |     |
| ---------------------- | --- | -------- | ---------- | --- |
| Availability           | Yes | Yes      | Yes        | Yes |
| Active Transform Rules | 10  | 25       | 50         | 300 |
| Regex support          | No  | No       | Yes        | Yes |

A Cloudflare user must have the [Firewall role](https://developers.cloudflare.com/fundamentals/manage-members/roles/) or one of the Administrator roles to access Transform Rules.

## Transform Rules evaluation

Managed Transforms run before other types of Transform Rules that modify HTTP headers:

* Managed Transforms that adjust HTTP request headers run before Request Header Transform Rules.
* Managed Transforms that adjust HTTP response headers run before Response Header Transform Rules.

Transform Rules run in order. Rules that appear later in the list of Transform Rules can overwrite changes done by previous rules. You can define the rule order in the dashboard or via API.

Request and response fields are immutable within each [phase](https://developers.cloudflare.com/ruleset-engine/about/phases/) while evaluating Transform Rules for a request/response. For more information, refer to [Field values during rule evaluation](https://developers.cloudflare.com/ruleset-engine/about/rules/#field-values-during-rule-evaluation).

Warning

Using Cloudflare challenges along with Rules features such as Transform Rules may cause challenge loops. Refer to [Rules troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/) for more information.

## Troubleshooting

When troubleshooting Transform Rules, use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to determine if a rule is triggering for a specific URL.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}}]}
```

---

---
title: Transform Rules examples
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Transform Rules examples

Filter resources...

[Add a wildcard CORS response headerCreate a CORS response header transform rule to add an Access-Control-Allow-Origin HTTP header to the response with wildcard as static value. (cookiename=value).](https://developers.cloudflare.com/rules/transform/examples/add-cors-header/)[Add a request header with the current bot scoreCreate a request header transform rule to add a X-Bot-Score HTTP header to the request with the current bot score.](https://developers.cloudflare.com/rules/transform/examples/add-request-header-bot-score/)[Add request header with a static valueCreate a request header transform rule to add an X-Source HTTP header to the request with a static value (Cloudflare).](https://developers.cloudflare.com/rules/transform/examples/add-request-header-static-value/)[Add a request header for subrequests from other zonesCreate a request header transform rule to add an HTTP header when the Workers subrequest comes from a different zone.](https://developers.cloudflare.com/rules/transform/examples/add-request-header-subrequest-other-zone/)[Add a response header with a static valueCreate a response header transform rule to add a set-cookie HTTP header to the response with a static value (cookiename=value).](https://developers.cloudflare.com/rules/transform/examples/add-response-header-static-value/)[Normalize encoded slashes in URL pathCreate a URL rewrite rule (part of Transform Rules) to normalize encoded forward slashes (%2F) in the request path to standard slashes (/).](https://developers.cloudflare.com/rules/transform/examples/normalize-encoded-slash/)[Remove a request headerCreate a request header transform rule (part of Transform Rules) to remove the cf-connecting-ip HTTP header from the request.](https://developers.cloudflare.com/rules/transform/examples/remove-request-header/)[Remove a response headerCreate a response header transform rule (part of Transform Rules) to remove the cf-connecting-ip HTTP header from the response.](https://developers.cloudflare.com/rules/transform/examples/remove-response-header/)[Rewrite blog archive URLsCreate a transform rule to rewrite the URL format /posts/<YYYY>-<MM>-<DD>-<TITLE> to the new format /posts/<YYYY>/<MM>/<DD>/<TITLE>.](https://developers.cloudflare.com/rules/transform/examples/rewrite-archive-urls-new-format/)[Rewrite path of moved section of a websiteCreate a URL rewrite rule (part of Transform Rules) to rewrite everything under /blog/<PATH> to /marketing/<PATH>.](https://developers.cloudflare.com/rules/transform/examples/rewrite-moved-section/)[Rewrite path of archived blog postsCreate a URL rewrite rule (part of Transform Rules) to rewrite any requests for /news/2012/... URI paths to /archive/news/2012/....](https://developers.cloudflare.com/rules/transform/examples/rewrite-path-archived-posts/)[Rewrite path for object storage bucketCreate a URL rewrite rule (part of Transform Rules) to rewrite any requests for /files/... URI paths to /....](https://developers.cloudflare.com/rules/transform/examples/rewrite-path-object-storage/)[Rewrite image paths with several URL segmentsCreate a URL rewrite rule (part of Transform Rules) to rewrite any requests for /images/<FOLDER1>/<FOLDER2>/<FILENAME> to /img/<FILENAME>.](https://developers.cloudflare.com/rules/transform/examples/rewrite-several-url-different-url/)[Rewrite URL query stringCreate a transform rule to rewrite the request path from /blog to /blog?sort-by=date.](https://developers.cloudflare.com/rules/transform/examples/rewrite-url-string-visitors/)[Rewrite page path for visitors in specific countriesCreate two URL rewrite rules (part of Transform Rules) to rewrite the path of the welcome page for visitors in specific countries.](https://developers.cloudflare.com/rules/transform/examples/rewrite-welcome-for-countries/)[Set a response header with the current bot scoreCreate a response header transform rule (part of Transform Rules) to set an X-Bot-Score HTTP header in the response with the current bot score.](https://developers.cloudflare.com/rules/transform/examples/set-response-header-bot-score/)[Set response header with a static valueCreate a response header transform rule (part of Transform Rules) to set an X-Bot-Score HTTP header in the response to a static value (Cloudflare).](https://developers.cloudflare.com/rules/transform/examples/set-response-header-static-value/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}}]}
```

---

---
title: Add a wildcard CORS response header
description: Create a CORS response header transform rule to add an `Access-Control-Allow-Origin` HTTP header to the response with wildcard as static value. (`cookiename=value`).
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Response modification ](https://developers.cloudflare.com/search/?tags=Response%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/add-cors-header.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Add a wildcard CORS response header

Create a response header transform rule to add an `Access-Control-Allow-Origin` CORS HTTP header to the response with a static wildcard value.

The following response header transform rule adds a header named `Access-Control-Allow-Origin` with a static wildcard value (`*`) to the HTTP response:

Text in **Expression Editor**:

```

(http.host eq "<YOUR_HOSTNAME>")


```

Selected operation under **Modify response header**: _Set static_

**Header name**: `Access-Control-Allow-Origin`

**Value**: `*`

You can also use an expression similar to the following to apply the CORS header to several specific hostnames:

```

(http.host in {"<YOUR_HOSTNAME_1>" "<YOUR_HOSTNAME_2>"})


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/add-cors-header/","name":"Add a wildcard CORS response header"}}]}
```

---

---
title: Add a request header with the current bot score
description: Create a request header transform rule to add a `X-Bot-Score` HTTP header to the request with the current bot score.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Request modification ](https://developers.cloudflare.com/search/?tags=Request%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/add-request-header-bot-score.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Add a request header with the current bot score

Create a request header transform rule to add a `X-Bot-Score` HTTP header to the request with the current bot score.

The following request header transform rule adds a header named `X-Bot-Score` with the current bot score to the HTTP request:

Text in **Expression Editor**:

```

starts_with(http.request.uri.path, "/en/")


```

Selected operation under **Modify request header**: _Set dynamic_

**Header name**: `X-Bot-Score`

**Value**: `to_string(cf.bot_management.score)`

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/add-request-header-bot-score/","name":"Add a request header with the current bot score"}}]}
```

---

---
title: Add request header with a static value
description: Create a request header transform rule to add an `X-Source` HTTP header to the request with a static value (`Cloudflare`).
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Request modification ](https://developers.cloudflare.com/search/?tags=Request%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/add-request-header-static-value.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Add request header with a static value

Create a request header transform rule to add an `X-Source` HTTP header to the request with a static value (`Cloudflare`).

The following request header transform rule adds a header named `X-Source` with a static value (`Cloudflare`) to the HTTP request:

Text in **Expression Editor**:

```

starts_with(http.request.uri.path, "/en/")


```

Selected operation under **Modify request header**: _Set static_

**Header name**: `X-Source`

**Value**: `Cloudflare`

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/add-request-header-static-value/","name":"Add request header with a static value"}}]}
```

---

---
title: Add a request header for subrequests from other zones
description: Create a request header transform rule to add an HTTP header when the Workers subrequest comes from a different zone.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Request modification ](https://developers.cloudflare.com/search/?tags=Request%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/add-request-header-subrequest-other-zone.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Add a request header for subrequests from other zones

Create a request header transform rule to add an HTTP header when the Workers subrequest comes from a different zone.

The following request header transform rule adds an HTTP header to Workers subrequests coming from a different zone:

Text in **Expression Editor** (replace `myappexample.com` with your domain):

```

(cf.worker.upstream_zone != "" and cf.worker.upstream_zone != "myappexample.com")


```

Selected operation under **Modify request header**: _Set static_

**Header name**: `X-External-Workers-Subrequest`

**Value**: `1`

The [cf.worker.upstream\_zone](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.worker.upstream%5Fzone/) field used in the rule expression is set to empty if the current request is not a Workers subrequest.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/add-request-header-subrequest-other-zone/","name":"Add a request header for subrequests from other zones"}}]}
```

---

---
title: Add a response header with a static value
description: Create a response header transform rule to add a `set-cookie` HTTP header to the response with a static value (`cookiename=value`).
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Response modification ](https://developers.cloudflare.com/search/?tags=Response%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/add-response-header-static-value.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Add a response header with a static value

Create a response header transform rule to add a `set-cookie` HTTP header to the response with a static value (`cookiename=value`).

The following response header transform rule adds a header named `set-cookie` with a static value (`cookiename=value`) to the HTTP response:

Text in **Expression Editor**:

```

starts_with(http.request.uri.path, "/en/")


```

Selected operation under **Modify response header**: _Add_

**Header name**: `set-cookie`

**Value**: `cookiename=value`

This rule would keep any existing `set-cookie` headers already present in the HTTP response.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/add-response-header-static-value/","name":"Add a response header with a static value"}}]}
```

---

---
title: Normalize encoded slashes in URL path
description: Create a URL rewrite rule (part of Transform Rules) to normalize encoded forward slashes (`%2F`) in the request path to standard slashes (`/`).
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ URL rewrite ](https://developers.cloudflare.com/search/?tags=URL%20rewrite) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/normalize-encoded-slash.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Normalize encoded slashes in URL path

Create a URL rewrite rule (part of Transform Rules) to normalize encoded forward slashes (`%2F`) in the request path to standard slashes (`/`).

Different web servers and applications handle encoded forward slashes (`%2F`) in URLs differently. Cloudflare follows [RFC 3986 ↗](https://datatracker.ietf.org/doc/html/rfc3986), which specifies that `%2F` **should not** be automatically normalized to `/` because `/` is a reserved character in URLs, and decoding it might change the intended meaning of the path.

However, many origin servers **do** automatically decode `%2F` into `/` when processing requests. If your origin server behaves this way, you may want to apply the same normalization at Cloudflare’s edge to ensure consistency in request handling, rule evaluation, and logging.

## How to normalize `%2F`

To normalize encoded forward slashes (`%2F`) to standard slashes (`/`) in the request path before [subsequent](https://developers.cloudflare.com/ruleset-engine/reference/phases-list/) rule evaluation, create a new URL rewrite rule and define a dynamic URL path rewrite using [url\_decode()](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#url%5Fdecode) function:

Text in **Expression Editor**:

```

(lower(raw.http.request.full_uri) wildcard "*%2f*")


```

Text after **Path** \> **Rewrite to** \> _Dynamic_:

```

url_decode(http.request.uri.path)


```

This transformation ensures that `%2F` is always treated as `/` in the request path. This is particularly useful when setting up rules that depend on URL path matching, as it prevents discrepancies caused by differing normalization behaviors.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/normalize-encoded-slash/","name":"Normalize encoded slashes in URL path"}}]}
```

---

---
title: Remove a request header
description: Create a request header transform rule (part of Transform Rules) to remove the `cf-connecting-ip` HTTP header from the request.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Request modification ](https://developers.cloudflare.com/search/?tags=Request%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/remove-request-header.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Remove a request header

Create a request header transform rule (part of Transform Rules) to remove the `cf-connecting-ip` HTTP header from the request.

The following request header transform rule removes the `cf-connecting-ip` header from the HTTP request:

Text in **Expression Editor**:

```

starts_with(http.request.uri.path, "/private/")


```

Selected operation under **Modify request header**: _Remove_

**Header name**: `cf-connecting-ip`

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/remove-request-header/","name":"Remove a request header"}}]}
```

---

---
title: Remove a response header
description: Create a response header transform rule (part of Transform Rules) to remove the `cf-connecting-ip` HTTP header from the response.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Response modification ](https://developers.cloudflare.com/search/?tags=Response%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/remove-response-header.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Remove a response header

Create a response header transform rule (part of Transform Rules) to remove the `cf-connecting-ip` HTTP header from the response.

The following response header transform rule removes the `cf-connecting-ip` header from the HTTP response:

Text in **Expression Editor**:

```

starts_with(http.request.uri.path, "/private/")


```

Selected operation under **Modify response header**: _Remove_

**Header name**: `cf-connecting-ip`

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/remove-response-header/","name":"Remove a response header"}}]}
```

---

---
title: Rewrite blog archive URLs
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ URL rewrite ](https://developers.cloudflare.com/search/?tags=URL%20rewrite) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/rewrite-archive-urls-new-format.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Rewrite blog archive URLs

Create a transform rule to rewrite the URL format `/posts/<YYYY>-<MM>-<DD>-<TITLE>` to the new format `/posts/<YYYY>/<MM>/<DD>/<TITLE>`.

To rewrite the URLs of a blog archive that follow the URL format `/posts/<YYYY>-<MM>-<DD>-<TITLE>` to the new format `/posts/<YYYY>/<MM>/<DD>/<TITLE>`, create the following URL rewrite rule:

Text in **Expression Editor**:

```

http.request.uri.path ~ "^/posts/[0-9]+-[0-9]+-[0-9]+-.*"


```

Text after **Path** \> **Rewrite to** \> _Dynamic_:

```

regex_replace(http.request.uri.path, "^/posts/([0-9]+)-([0-9]+)-([0-9]+)-(.*)$", "/posts/${1}/${2}/${3}/${4}")


```

The function `regex_replace()` also allows you to extract parts of the URL using regular expressions' capture groups. Create capture groups by putting part of the regular expression in parentheses. Then, reference a capture group using `${<NUMBER>}` in the replacement string, where `<NUMBER>` is the number of the capture group.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/rewrite-archive-urls-new-format/","name":"Rewrite blog archive URLs"}}]}
```

---

---
title: Rewrite path of moved section of a website
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ URL rewrite ](https://developers.cloudflare.com/search/?tags=URL%20rewrite) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/rewrite-moved-section.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Rewrite path of moved section of a website

Create a URL rewrite rule (part of Transform Rules) to rewrite everything under `/blog/<PATH>` to `/marketing/<PATH>`.

To rewrite everything under `/blog/<PATH>` to `/marketing/<PATH>`, create a new URL rewrite rule and define a dynamic URL path rewrite using [wildcard pattern parameters](https://developers.cloudflare.com/rules/transform/url-rewrite/create-dashboard/#wildcard-pattern-parameters):

**When incoming requests match**

* **Wildcard pattern**  
   * **Request URL**: `https://<YOUR_HOSTNAME>/blog/*`

**Then rewrite the path and/or query**

* **Target path**: \[`/`\] `blog/*`
* **Rewrite to**: \[`/`\] `marketing/${1}`

Make sure to replace `<YOUR_HOSTNAME>` with your actual hostname and adjust the example paths according to your setup.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/rewrite-moved-section/","name":"Rewrite path of moved section of a website"}}]}
```

---

---
title: Rewrite path of archived blog posts
description: Create a URL rewrite rule (part of Transform Rules) to rewrite any requests for `/news/2012/...` URI paths to `/archive/news/2012/...`.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ URL rewrite ](https://developers.cloudflare.com/search/?tags=URL%20rewrite) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/rewrite-path-archived-posts.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Rewrite path of archived blog posts

Create a URL rewrite rule (part of Transform Rules) to rewrite any requests for `/news/2012/...` URI paths to `/archive/news/2012/...`.

To rewrite all requests to `/news/2012/...` to `/archive/news/2012/...` you must add a reference to the content of the original URL. Create a new URL rewrite rule and define a dynamic URL path rewrite using [wildcard pattern parameters](https://developers.cloudflare.com/rules/transform/url-rewrite/create-dashboard/#wildcard-pattern-parameters):

**When incoming requests match**

* **Wildcard pattern**  
   * **Request URL**: `https://<YOUR_HOSTNAME>/news/2012/*`

**Then rewrite the path and/or query**

* **Target path**: \[`/`\] `news/2012/*`
* **Rewrite to**: \[`/`\] `archive/news/2012/${1}`

Make sure to replace `<YOUR_HOSTNAME>` with your actual hostname and adjust the example paths according to your setup.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/rewrite-path-archived-posts/","name":"Rewrite path of archived blog posts"}}]}
```

---

---
title: Rewrite path for object storage bucket
description: Create a URL rewrite rule (part of Transform Rules) to rewrite any requests for `/files/...` URI paths to `/...`.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ URL rewrite ](https://developers.cloudflare.com/search/?tags=URL%20rewrite) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/rewrite-path-object-storage.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Rewrite path for object storage bucket

Create a URL rewrite rule (part of Transform Rules) to remove `/files/` from URI paths before routing request to your object storage bucket.

To remove `/files/` from URI paths before routing request to your object storage bucket, create a new URL rewrite rule and define a dynamic URL path rewrite using [wildcard pattern parameters](https://developers.cloudflare.com/rules/transform/url-rewrite/create-dashboard/#wildcard-pattern-parameters):

**When incoming requests match**

* **Wildcard pattern**  
   * **Request URL**: `https://<YOUR_HOSTNAME>/files/*`

**Then rewrite the path and/or query**

* **Target path**: \[`/`\] `files/*`
* **Rewrite to**: \[`/`\] `${1}`

Make sure to replace `<YOUR_HOSTNAME>` with your actual hostname and adjust the example paths according to your setup. Then, use [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/) to route traffic to an object storage bucket.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/rewrite-path-object-storage/","name":"Rewrite path for object storage bucket"}}]}
```

---

---
title: Rewrite image paths with several URL segments
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ URL rewrite ](https://developers.cloudflare.com/search/?tags=URL%20rewrite) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/rewrite-several-url-different-url.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Rewrite image paths with several URL segments

Create a URL rewrite rule (part of Transform Rules) to rewrite any requests for `/images/<FOLDER1>/<FOLDER2>/<FILENAME>` to `/img/<FILENAME>`.

To rewrite paths like `/images/<FOLDER1>/<FOLDER2>/<FILENAME>` — where `<FOLDER1>`, `<FOLDER2>`, and `<FILENAME>` can vary — to `/img/<FILENAME>`, create a URL rewrite rule with a dynamic rewrite of the path component:

Text in **Expression Editor**:

```

http.request.uri.path ~ "^/images/[^/]+/[^/]+/[^/]+$"


```

Text after **Path** \> **Rewrite to** \> _Dynamic_:

```

regex_replace(http.request.uri.path, "^/images/[^/]+/[^/]+/(.+)$", "/img/${1}")


```

For example, this rule would rewrite the `/images/nature/animals/tiger.png` path to `/img/tiger.png`.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/rewrite-several-url-different-url/","name":"Rewrite image paths with several URL segments"}}]}
```

---

---
title: Rewrite URL query string
description: Create a transform rule to rewrite the request path from `/blog` to `/blog?sort-by=date`.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ URL rewrite ](https://developers.cloudflare.com/search/?tags=URL%20rewrite) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/rewrite-url-string-visitors.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Rewrite URL query string

Create a transform rule to rewrite the request path from `/blog` to `/blog?sort-by=date`.

To rewrite a request to the `/blog` path to `/blog?sort-by=date`, create a URL rewrite rule with the following settings:

Text in **Expression Editor**:

```

http.request.uri.path == "/blog"


```

Text after **Query** \> **Rewrite to** \> _Static_:

```

sort-by=date


```

Additionally, set the path rewrite action of the same rule to _Preserve_ so that the URL path does not change.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/rewrite-url-string-visitors/","name":"Rewrite URL query string"}}]}
```

---

---
title: Rewrite page path for visitors in specific countries
description: Create two URL rewrite rules (part of Transform Rules) to rewrite the path of the welcome page for visitors in specific countries.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ URL rewrite ](https://developers.cloudflare.com/search/?tags=URL%20rewrite) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/rewrite-welcome-for-countries.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Rewrite page path for visitors in specific countries

Create two URL rewrite rules (part of Transform Rules) to rewrite the path of the welcome page for visitors in specific countries.

To have a welcome page in two languages, create two URL rewrite rules with a static rewrite of the path component:

**URL rewrite rule #1**

Text in **Expression Editor**:

```

http.request.uri.path == "/welcome.html" && ip.src.country == "GB"


```

Text after **Path** \> **Rewrite to** \> _Static_:

```

/welcome-gb.html


```

**URL rewrite rule #2**

Text in **Expression Editor**:

```

http.request.uri.path == "/welcome.html" && ip.src.country == "PT"


```

Text after **Path** \> **Rewrite to** \> _Static_:

```

/welcome-pt.html


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/rewrite-welcome-for-countries/","name":"Rewrite page path for visitors in specific countries"}}]}
```

---

---
title: Set a response header with the current bot score
description: Create a response header transform rule (part of Transform Rules) to set an `X-Bot-Score` HTTP header in the response with the current bot score.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Response modification ](https://developers.cloudflare.com/search/?tags=Response%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/set-response-header-bot-score.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Set a response header with the current bot score

Create a response header transform rule (part of Transform Rules) to set an `X-Bot-Score` HTTP header in the response with the current bot score.

The following response header transform rule sets a header named `X-Bot-Score` to the current bot score in the HTTP response:

Text in **Expression Editor**:

```

starts_with(http.request.uri.path, "/en/")


```

Selected operation under **Modify response header**: _Set dynamic_

**Header name**: `X-Bot-Score`

**Value**: `to_string(cf.bot_management.score)`

This rule would overwrite any existing `X-Bot-Score` headers already present in the HTTP response.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/set-response-header-bot-score/","name":"Set a response header with the current bot score"}}]}
```

---

---
title: Set response header with a static value
description: Create a response header transform rule (part of Transform Rules) to set an `X-Bot-Score` HTTP header in the response to a static value (`Cloudflare`).
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

### Tags

[ Response modification ](https://developers.cloudflare.com/search/?tags=Response%20modification) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/examples/set-response-header-static-value.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Set response header with a static value

Create a response header transform rule (part of Transform Rules) to set an `X-Bot-Score` HTTP header in the response to a static value (`Cloudflare`).

The following response header transform rule sets a header named `X-Source` to a static value (`Cloudflare`) in the HTTP response:

Text in **Expression Editor**:

```

starts_with(http.request.uri.path, "/en/")


```

Selected operation under **Modify response header**: _Set static_

**Header name**: `X-Source`

**Value**: `Cloudflare`

This rule would overwrite any existing `X-Source` headers already present in the HTTP response.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/examples/","name":"Transform Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/examples/set-response-header-static-value/","name":"Set response header with a static value"}}]}
```

---

---
title: Managed Transforms
description: Managed Transforms allow you to perform common adjustments to HTTP request and response headers with the click of a button. The available adjustments include:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/managed-transforms/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Managed Transforms

Managed Transforms allow you to perform common adjustments to HTTP request and response headers with the click of a button. The available adjustments include:

* Add bot protection request headers.
* Remove or add headers related to the visitor's IP address.
* Add request header when the WAF detects leaked credentials.
* Add security-related response headers.
* Remove "X-Powered-By" response headers.

For a complete list, refer to [Available Managed Transforms](https://developers.cloudflare.com/rules/transform/managed-transforms/reference/).

When you enable a Managed Transform, Cloudflare internally deploys one or more Transform Rules to handle the common configuration you selected. These generated rules will not count against the [maximum number of Transform Rules](https://developers.cloudflare.com/rules/transform/#availability) available in your Cloudflare plan.

Enabled Managed Transforms will apply to all inbound requests for the zone.

Note

The generated internal Transform Rules will not appear in the Transform Rules list in the Cloudflare dashboard.

## Next steps

For dashboard, API, and Terraform instructions, refer to [Configure Managed Transforms](https://developers.cloudflare.com/rules/transform/managed-transforms/configure/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/managed-transforms/","name":"Managed Transforms"}}]}
```

---

---
title: Configure Managed Transforms
description: Learn how to configure Managed Transforms.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/managed-transforms/configure.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Configure Managed Transforms

* [ Dashboard ](#tab-panel-6078)
* [ API ](#tab-panel-6079)
* [ Terraform ](#tab-panel-6080)

1. In the Cloudflare dashboard, go to the Rules **Settings** page.  
[ Go to **Settings** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/settings)
2. In the **Managed Transforms** tab, enable or disable the [desired Managed Transforms](https://developers.cloudflare.com/rules/transform/managed-transforms/reference/) by selecting the toggle next to each entry. Some Managed Transforms may not be available in your Cloudflare plan or product subscriptions.

**1\. Get list of available Managed Transforms**

Check the Managed Transform's current status and availability using the [List Managed Transforms](https://developers.cloudflare.com/api/resources/managed%5Ftransforms/methods/list/) operation.

The following example request obtains a list of available Managed Transforms, organized by request or response, with information about their current status (`enabled` field) and if you can update them, based on conflicts with other enabled Managed Transforms (`has_conflict` field).

Each Managed Transform item will optionally contain a `conflicts_with` array informing you about any Managed Transforms that will conflict with the current Managed Transform when enabled.

The response will only include available Managed Transforms according to your Cloudflare plan and product subscriptions.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Response Compression Read`
* `Config Settings Write`
* `Config Settings Read`
* `Dynamic URL Redirects Write`
* `Dynamic URL Redirects Read`
* `Cache Settings Write`
* `Cache Settings Read`
* `Custom Errors Write`
* `Custom Errors Read`
* `Origin Write`
* `Origin Read`
* `Managed headers Write`
* `Managed headers Read`
* `Zone Transform Rules Write`
* `Zone Transform Rules Read`
* `Mass URL Redirects Write`
* `Mass URL Redirects Read`
* `Magic Firewall Write`
* `Magic Firewall Read`
* `L4 DDoS Managed Ruleset Write`
* `L4 DDoS Managed Ruleset Read`
* `HTTP DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Read`
* `Sanitize Write`
* `Sanitize Read`
* `Transform Rules Write`
* `Transform Rules Read`
* `Select Configuration Write`
* `Select Configuration Read`
* `Bot Management Write`
* `Bot Management Read`
* `Zone WAF Write`
* `Zone WAF Read`
* `Account WAF Write`
* `Account WAF Read`
* `Account Rulesets Read`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Read`
* `Logs Write`
* `Logs Read`

List Managed Transforms

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/managed_headers" \

  --request GET \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"


```

```

{

  "result": {

    "managed_request_headers": [

      {

        "enabled": false,

        "has_conflict": false,

        "id": "add_bot_protection_headers"

      },

32 collapsed lines

      {

        "enabled": false,

        "has_conflict": false,

        "id": "add_client_certificate_headers"

      },

      {

        "enabled": false,

        "has_conflict": false,

        "id": "add_visitor_location_headers"

      },

      {

        "conflicts_with": ["remove_visitor_ip_headers"],

        "enabled": false,

        "has_conflict": false,

        "id": "add_true_client_ip_headers"

      },

      {

        "conflicts_with": ["add_true_client_ip_headers"],

        "enabled": false,

        "has_conflict": false,

        "id": "remove_visitor_ip_headers"

      },

      {

        "enabled": false,

        "has_conflict": false,

        "id": "add_waf_credential_check_status_header"

      },

      {

        "enabled": false,

        "has_conflict": false,

        "id": "add_waf_content_scan_status_header"

      }

    ],

    "managed_response_headers": [

      {

        "enabled": false,

        "has_conflict": false,

        "id": "remove_x-powered-by_header"

      },

5 collapsed lines

      {

        "enabled": false,

        "has_conflict": false,

        "id": "add_security_headers"

      }

    ]

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

**2\. Change the status of Managed Transforms**

Change the status of the [desired Managed Transforms](https://developers.cloudflare.com/rules/transform/managed-transforms/reference/) using the [Update status of Managed Transforms](https://developers.cloudflare.com/api/resources/managed%5Ftransforms/methods/edit/) operation.

Add the Managed Transforms you wish to change to the request body, and update their status in the `enabled` field. You cannot enable a Managed Transform that has a conflict with a currently enabled Managed Transform (that is, an item where `has_conflict` is `true`).

Make sure you include the Managed Transforms you are updating in the correct JSON object (`managed_request_headers` or `managed_response_headers`).

The response will include all the available Managed Transforms and their new status after the update.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update Managed Transforms

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/managed_headers" \

  --request PATCH \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "managed_request_headers": [

        {

            "id": "add_visitor_location_headers",

            "enabled": true

        }

    ],

    "managed_response_headers": [

        {

            "id": "remove_x-powered-by_header",

            "enabled": true

        }

    ]

  }'


```

```

{

  "result": {

    "managed_request_headers": [

10 collapsed lines

      {

        "enabled": false,

        "has_conflict": false,

        "id": "add_bot_protection_headers"

      },

      {

        "enabled": false,

        "has_conflict": false,

        "id": "add_client_certificate_headers"

      },

      {

        "enabled": true,

        "has_conflict": false,

        "id": "add_visitor_location_headers"

      },

22 collapsed lines

      {

        "conflicts_with": ["remove_visitor_ip_headers"],

        "enabled": false,

        "has_conflict": false,

        "id": "add_true_client_ip_headers"

      },

      {

        "conflicts_with": ["add_true_client_ip_headers"],

        "enabled": false,

        "has_conflict": false,

        "id": "remove_visitor_ip_headers"

      },

      {

        "enabled": false,

        "has_conflict": false,

        "id": "add_waf_credential_check_status_header"

      },

      {

        "enabled": false,

        "has_conflict": false,

        "id": "add_waf_content_scan_status_header"

      }

    ],

    "managed_response_headers": [

      {

        "enabled": true,

        "has_conflict": false,

        "id": "remove_x-powered-by_header"

      },

5 collapsed lines

      {

        "enabled": false,

        "has_conflict": false,

        "id": "add_security_headers"

      }

    ]

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Note

Terraform code snippets below refer to the v4 SDK only.

Use the `cloudflare_managed_headers` Terraform resource to configure Managed Transforms. For example:

```

resource "cloudflare_managed_headers" "tf_example" {

  zone_id = "<ZONE_ID>"


  managed_request_headers {

    id      = "add_visitor_location_headers"

    enabled = true

  }


  managed_response_headers {

    id      = "remove_x-powered-by_header"

    enabled = true

  }

}


```

Make sure you include the Managed Transforms you are updating in the correct object (`managed_request_headers` or `managed_response_headers`).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/managed-transforms/","name":"Managed Transforms"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/managed-transforms/configure/","name":"Configure Managed Transforms"}}]}
```

---

---
title: Available Managed Transforms
description: Learn about Cloudflare's Managed Transforms for modifying HTTP headers, including bot protection, TLS client auth, and leaked credentials checks.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/managed-transforms/reference.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Available Managed Transforms

This page lists the available Managed Transforms. They can modify HTTP request headers or response headers.

For more complex and customized header modifications, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

## Important remarks

* Enabling a Managed Transform may cause issues in your website. You should test any changes in a staging environment. If you detect any undesired or unexpected behavior, consider disabling the Managed Transform and creating a partial implementation using your own transform rule.
* The names of HTTP headers are case-insensitive. Cloudflare may use a capitalization different from the one presented in this page. Make sure that your origin server can handle HTTP request headers regardless of the exact capitalization of their names.

## HTTP request headers

### Add bot protection headers

Note

Requires an Enterprise plan with [Bot Management](https://developers.cloudflare.com/bots/plans/bm-subscription/) enabled.

Adds HTTP headers with bot-related values to the request sent to the origin server:

* `cf-bot-score`: Contains the [bot score](https://developers.cloudflare.com/bots/concepts/bot-score/) (for example, `30`).
* `cf-verified-bot`: Contains `true` if the request comes from a [verified bot](https://developers.cloudflare.com/bots/concepts/bot/verified-bots/), or `false` otherwise.
* `cf-ja3-hash`: Contains the [JA3 fingerprint](https://developers.cloudflare.com/bots/additional-configurations/ja3-ja4-fingerprint/).
* `cf-ja4`: Contains the [JA4 fingerprint](https://developers.cloudflare.com/bots/additional-configurations/ja3-ja4-fingerprint/).

### Add TLS client auth headers

Adds HTTP headers with [Mutual TLS](https://developers.cloudflare.com/api-shield/security/mtls/) (mTLS) client authentication values to the request sent to the origin server:

* `cf-cert-revoked`: Value from the [cf.tls\_client\_auth.cert\_revoked](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Frevoked/) field.
* `cf-cert-verified`: Value from the [cf.tls\_client\_auth.cert\_verified](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fverified/) field.
* `cf-cert-presented`: Value from the [cf.tls\_client\_auth.cert\_presented](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fpresented/) field.
* `cf-cert-issuer-dn`: Value from the [cf.tls\_client\_auth.cert\_issuer\_dn](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fissuer%5Fdn/) field.
* `cf-cert-subject-dn`: Value from the [cf.tls\_client\_auth.cert\_subject\_dn](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fsubject%5Fdn/) field.
* `cf-cert-issuer-dn-rfc2253`: Value from the [cf.tls\_client\_auth.cert\_issuer\_dn\_rfc2253](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fissuer%5Fdn%5Frfc2253/) field.
* `cf-cert-subject-dn-rfc2253`: Value from the [cf.tls\_client\_auth.cert\_subject\_dn\_rfc2253](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fsubject%5Fdn%5Frfc2253/) field.
* `cf-cert-issuer-dn-legacy`: Value from the [cf.tls\_client\_auth.cert\_issuer\_dn\_legacy](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fissuer%5Fdn%5Flegacy/) field.
* `cf-cert-subject-dn-legacy`: Value from the [cf.tls\_client\_auth.cert\_subject\_dn\_legacy](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fsubject%5Fdn%5Flegacy/) field.
* `cf-cert-serial`: Value from the [cf.tls\_client\_auth.cert\_serial](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fserial/) field.
* `cf-cert-issuer-serial`: Value from the [cf.tls\_client\_auth.cert\_issuer\_serial](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fissuer%5Fserial/) field.
* `cf-cert-fingerprint-sha256`: Value from the [cf.tls\_client\_auth.cert\_fingerprint\_sha256](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Ffingerprint%5Fsha256/) field.
* `cf-cert-fingerprint-sha1`: Value from the [cf.tls\_client\_auth.cert\_fingerprint\_sha1](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Ffingerprint%5Fsha1/) field.
* `cf-cert-not-before`: Value from the [cf.tls\_client\_auth.cert\_not\_before](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fnot%5Fbefore/) field.
* `cf-cert-not-after`: Value from the [cf.tls\_client\_auth.cert\_not\_after](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fnot%5Fafter/) field.
* `cf-cert-ski`: Value from the [cf.tls\_client\_auth.cert\_ski](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fski/) field.
* `cf-cert-issuer-ski`: Value from the [cf.tls\_client\_auth.cert\_issuer\_ski](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.tls%5Fclient%5Fauth.cert%5Fissuer%5Fski/) field.

### Add visitor location headers

Adds HTTP headers with location information for the visitor's IP address to the request sent to the origin server:

* `cf-ipcity`: The visitor's city (value from the [ip.src.city](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.city/) field).
* `cf-ipcountry`: The visitor's country (value from the [ip.src.country](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.country/) field).
* `cf-ipcontinent`: The visitor's continent (value from the [ip.src.continent](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.continent/) field).
* `cf-iplongitude`: The visitor's longitude (value from the [ip.src.lon](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.lon/) field).
* `cf-iplatitude`: The visitor's latitude (value from the [ip.src.lat](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.lat/) field).
* `cf-region`: The visitor's region (value from the [ip.src.region](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.region/) field).
* `cf-region-code`: The visitor's region code (value from the [ip.src.region\_code](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.region%5Fcode/) field).
* `cf-metro-code`: The visitor's metro code (value from the [ip.src.metro\_code](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.metro%5Fcode/) field).
* `cf-postal-code`: The visitor's postal code (value from the [ip.src.postal\_code](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.postal%5Fcode/) field).
* `cf-timezone`: The name of the visitor's timezone (value from the [ip.src.timezone.name](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.timezone.name/) field).

Note

Turning on [IP geolocation](https://developers.cloudflare.com/network/ip-geolocation/) will send a `cf-ipcountry` HTTP header to your origin server even when **Add visitor location headers** is turned off.

#### Encoding of non-ASCII header values

Cloudflare always converts non-ASCII characters to UTF-8 in HTTP request and response header values. This applies to location headers added by the **Add visitor location headers** managed transform.

### Add "True-Client-IP" header

Note

Only available on Enterprise plans.

Adds a `true-client-ip` request header with the visitor's IP address.

This Managed Transform is unavailable when [**Remove visitor IP headers**](#remove-visitor-ip-headers) is enabled.

### Remove visitor IP headers

Removes HTTP headers that may contain the visitor's IP address from the request sent to the origin server. Handles the following HTTP request headers:

* `cf-connecting-ip`
* `x-forwarded-for` (refer to the [notes](#visitor-ip-address-in-the-x-forwarded-for-http-header) below)
* `true-client-ip`

This Managed Transform is unavailable when [**Add "True-Client-IP" header**](#add-true-client-ip-header) is enabled.

#### Visitor IP address in the `x-forwarded-for` HTTP header

For the `x-forwarded-for` HTTP request header, enabling **Remove visitor IP headers** will only remove the visitor IP from the header value when Cloudflare receives a request proxied by at least another CDN (content delivery network). In this case, Cloudflare will only keep the IP address of the last proxy.

For example, consider an incoming request proxied by two CDNs (`CDN_1` and `CDN_2`) before reaching the Cloudflare network. The `x-forwarded-for` header would be similar to the following:  
`x-forwarded-for: <VISITOR_IP>, <THIRD_PARTY_CDN_1_IP>, <THIRD_PARTY_CDN_2_IP>`

With **Remove visitor IP headers** enabled, the `x-forwarded-for` header sent to the origin server will be:  
`x-forwarded-for: <THIRD_PARTY_CDN_2_IP>`

### Add leaked credentials checks header

Adds an `Exposed-Credential-Check` request header whenever the WAF detects leaked credentials in the incoming request.

The header can have these values:

| Header + Value              | Description                                                             | Availability       |
| --------------------------- | ----------------------------------------------------------------------- | ------------------ |
| Exposed-Credential-Check: 1 | Previously leaked username and password detected                        | Pro plan and above |
| Exposed-Credential-Check: 2 | Previously leaked username detected                                     | Enterprise plan    |
| Exposed-Credential-Check: 3 | Similar combination of previously leaked username and password detected | Enterprise plan    |
| Exposed-Credential-Check: 4 | Previously leaked password detected                                     | All plans          |

You will only receive this managed header at your origin server if:

* The [leaked credentials detection](https://developers.cloudflare.com/waf/detections/leaked-credentials/) in the WAF is turned on.
* The **Add Leaked Credentials Checks Header** managed transform is turned on.
* Your Cloudflare plan supports the type of credentials detection. For example, Free plans can only know if a password was previously leaked. In this situation, Cloudflare will add an `Exposed-Credential-Check: 4` header to the request.

### Add malicious uploads detection header

Adds a `Malicious-Uploads-Detection` request header indicating the outcome of scanning uploaded content for malicious signatures.

The header can have one of the following values:

| Header + Value                 | Description                                                                                                                                                                                                                                             |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Malicious-Uploads-Detection: 1 | The request contains at least one malicious content object ([cf.waf.content\_scan.has\_malicious\_obj](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.waf.content%5Fscan.has%5Fmalicious%5Fobj/) is true).         |
| Malicious-Uploads-Detection: 2 | The file scanner was unable to scan all the content objects detected in the request ([cf.waf.content\_scan.has\_failed](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.waf.content%5Fscan.has%5Ffailed/) is true). |
| Malicious-Uploads-Detection: 3 | The request contains at least one content object ([cf.waf.content\_scan.has\_obj](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.waf.content%5Fscan.has%5Fobj/) is true).                                          |

For more information, refer to [Malicious uploads detection](https://developers.cloudflare.com/waf/detections/malicious-uploads/).

## HTTP response headers

### Remove "X-Powered-By" headers

Removes the `X-Powered-By` HTTP response header that provides information about the application at the origin server that handled the request.

### Add security headers

Note

Adding the following security headers may have an impact on your website, such as blocking resources or triggering certificate errors. If you find any issues, try disabling the Managed Transform to isolate the possible cause.

Adds several security-related HTTP response headers. The added response headers and values are the following:

* `x-content-type-options: nosniff`
* `x-xss-protection: 1; mode=block`
* `x-frame-options: SAMEORIGIN`
* `referrer-policy: same-origin`
* `expect-ct: max-age=86400, enforce`

To increase protection, [enable HTTP Strict Transport Security (HSTS)](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/http-strict-transport-security/) for your website.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/managed-transforms/","name":"Managed Transforms"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/managed-transforms/reference/","name":"Available Managed Transforms"}}]}
```

---

---
title: Request Header Transform Rules
description: Learn how to modify HTTP request headers with Cloudflare's rules.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/request-header-modification/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Request Header Transform Rules

Use Request Header Transform Rules to manipulate the headers of HTTP requests sent to your origin server.

flowchart LR
accTitle: Header modifications diagram
accDescr: Header transform rules can change the headers sent to your origin server (request header modifications) or sent your your website visitors (response header modifications).

A[Visitor]
B((Cloudflare))
C[(Origin server)]

A -.-> B == "Includes request<br> header modifications" ==> C
C -.-> B -. "Includes response<br> header modifications" .-> A

style A stroke-width: 2px
style B stroke: orange,fill: orange,color: black
linkStyle 0,2,3 stroke-width: 1px
linkStyle 1 stroke-width: 3px

  
To modify HTTP headers in the **response** sent to website visitors, refer to [Response Header Transform Rules](https://developers.cloudflare.com/rules/transform/response-header-modification/).

Through Request Header Transform Rules you can:

* Set the value of an HTTP request header to a literal string value, overwriting its previous value or adding a new header to the request.
* Set the value of an HTTP request header according to an expression, overwriting its previous value or adding a new header to the request.
* Remove an HTTP header from the request.

You can create a request header transform rule [in the dashboard](https://developers.cloudflare.com/rules/transform/request-header-modification/create-dashboard/), [via API](https://developers.cloudflare.com/rules/transform/request-header-modification/create-api/), or [using Terraform](https://developers.cloudflare.com/terraform/additional-configurations/transform-rules/#create-a-request-header-transform-rule).

For more complex request header modifications, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

## Important remarks

* You cannot modify or remove HTTP request headers whose name starts with `x-cf-` or `cf-` except for the `cf-connecting-ip` HTTP request header, which you can remove.
* Due to protocol compliance reasons, modifying or removing request headers with [forbidden header names ↗](https://developer.mozilla.org/en-US/docs/Glossary/Forbidden%5Fheader%5Fname) (such as `Accept-Encoding`) is generally not allowed in Request Header Transform Rules.
* You cannot modify the value of any header commonly used to identify the website visitor's IP address or initial protocol, such as `x-forwarded-for`, `true-client-ip`, `x-real-ip`, or `x-forwarded-proto`.
* Although you can remove the `x-forwarded-for` header, it will be added back by Cloudflare's cache service (with a different value), and this header will reach your origin server. If you remove the `x-forwarded-for` header and the request is handled by Cloudflare Workers — which [run before the cache](https://developers.cloudflare.com/workers/reference/how-the-cache-works/) — the `x-forwarded-for` request header will be absent.
* You cannot set or modify the value of `cookie` HTTP request headers, but you can remove these headers. Configuring a rule that removes the `cookie` HTTP request header will remove all `cookie` headers in matching requests.
* If you modify the value of an existing HTTP request header using an expression that evaluates to an empty string (`""`) or an undefined value, the HTTP request header is **removed**.
* The HTTP request header removal operation will remove all request headers with the provided name.
* Currently, there is a limited number of HTTP request headers that you cannot modify. Cloudflare may remove restrictions for some of these HTTP request headers when presented with valid use cases. [Create a post in the community ↗](https://community.cloudflare.com) for consideration.
* To use [claims inside a JSON Web Token (JWT)](https://developers.cloudflare.com/api-shield/security/jwt-validation/transform-rules/), you must first set up a token validation configuration in API Shield.
* Request header transform rules run in order, and later rules can overwrite changes done by previous rules.
* The values of request and response fields are immutable within each [phase](https://developers.cloudflare.com/ruleset-engine/about/phases/), such as the `http_request_late_transform` phase where request header transform rules are defined. This means that later request header transform rules will not match based on changes done by previous request header transform rules. Refer to [Field values during rule evaluation](https://developers.cloudflare.com/ruleset-engine/about/rules/#field-values-during-rule-evaluation) for more information.

## Execution order

The execution order of Rules features is the following:

* [Single Redirects](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/)
* [URL Rewrite Rules](https://developers.cloudflare.com/rules/transform/url-rewrite/)
* [Configuration Rules](https://developers.cloudflare.com/rules/configuration-rules/)
* [Origin Rules](https://developers.cloudflare.com/rules/origin-rules/)
* [Bulk Redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/)
* [Managed Transforms](https://developers.cloudflare.com/rules/transform/managed-transforms/)
* [Request Header Transform Rules](https://developers.cloudflare.com/rules/transform/request-header-modification/)
* [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/)
* [Snippets](https://developers.cloudflare.com/rules/snippets/)
* [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/)

The different types of rules listed above will take precedence over [Page Rules](https://developers.cloudflare.com/rules/page-rules/). This means that Page Rules will be overridden if there is a match for both Page Rules and the Rules products listed above.

Generally speaking, for [non-terminating actions](https://developers.cloudflare.com/ruleset-engine/rules-language/actions/) the last change made by rules in the same [phase](https://developers.cloudflare.com/ruleset-engine/about/phases/) will win (later rules can overwrite changes done by previous rules). However, for terminating actions (_Block_, _Redirect_, or one of the challenge actions), rule evaluation will stop and the action will be executed immediately.

For example, if multiple rules with the _Redirect_ action match, Cloudflare will always use the URL redirect of the first rule that matches. Also, if you configure URL redirects using different Cloudflare products (Single Redirects and Bulk Redirects), the product executed first will apply, if there is a rule match (in this case, Single Redirects).

Refer to the [Phases list](https://developers.cloudflare.com/ruleset-engine/reference/phases-list/) for the product execution order.

Warning

Using Cloudflare challenges along with Rules features may cause challenge loops. Refer to [Rules troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/) for more information.

## Troubleshooting

When troubleshooting Request Header Transform Rules, use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to determine if a rule is triggering for a specific URL.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/request-header-modification/","name":"Request Header Transform Rules"}}]}
```

---

---
title: Create a request header transform rule via API
description: Use the Rulesets API to create Request Header Transform Rules via API. Refer to the Rules examples gallery for common use cases.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/request-header-modification/create-api.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a request header transform rule via API

Use the [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/) to create Request Header Transform Rules via API. Refer to the [Rules examples gallery](https://developers.cloudflare.com/rules/transform/examples/?operation=Request+modification) for common use cases.

If you are using Terraform, refer to [Transform Rules configuration using Terraform](https://developers.cloudflare.com/terraform/additional-configurations/transform-rules/#create-a-request-header-transform-rule).

## Basic rule settings

When creating a request header transform rule via API, make sure you:

* Set the rule action to `rewrite`.
* Define the [header modification parameters](https://developers.cloudflare.com/rules/transform/request-header-modification/reference/parameters/) in the `action_parameters` field according to the operation to perform (set or remove header).
* Deploy the rule to the `http_request_late_transform` phase at the zone level.

## Procedure

Follow this workflow to create a request header transform rule for a given zone via API:

1. Use the [List zone rulesets](https://developers.cloudflare.com/api/resources/rulesets/methods/list/) operation to check if there is already a ruleset for the `http_request_late_transform` phase at the zone level.
2. If the phase ruleset does not exist, create it using the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) operation. In the new ruleset properties, set the following values:  
   * **kind**: `zone`  
   * **phase**: `http_request_late_transform`
3. Use the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation to add a request header transform rule to the list of ruleset rules. Alternatively, include the rule in the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) request mentioned in the previous step.

Make sure your API token has the [required permissions](#required-api-token-permissions) to perform the API operations.

## Example requests

Example: Add an HTTP request header with a static value

The following example sets the rules of an existing phase ruleset (`$RULESET_ID`) to a single request header transform rule — adding an HTTP request header with a static value — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation. The response will contain the complete definition of the ruleset you updated.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "add_header_source",

            "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

            "description": "My first request header transform rule",

            "action": "rewrite",

            "action_parameters": {

                "headers": {

                    "X-Source": {

                        "operation": "set",

                        "value": "Cloudflare"

                    }

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "<RULESET_ID>",

    "name": "Zone-level Late Transform Ruleset",

    "description": "Zone-level ruleset that will execute Late Transform Rules.",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "ref": "add_header_source",

        "id": "<RULE_ID>",

        "version": "1",

        "action": "rewrite",

        "action_parameters": {

          "headers": {

            "X-Source": {

              "operation": "set",

              "value": "Cloudflare"

            }

          }

        },

        "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

        "description": "My first request header transform rule",

        "last_updated": "2021-04-14T14:42:04.219025Z",

        "ref": "<RULE_REF>"

      }

    ],

    "last_updated": "2021-04-14T14:42:04.219025Z",

    "phase": "http_request_late_transform"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

Example: Add an HTTP request header with a dynamic value

The following example sets the rules of an existing phase ruleset (`$RULESET_ID`) to a single request header transform rule — adding an HTTP request header with a dynamic value — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation. The response will contain the complete definition of the ruleset you updated.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "add_header_bot_score",

            "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

            "description": "My first request header transform rule",

            "action": "rewrite",

            "action_parameters": {

                "headers": {

                    "X-Bot-Score": {

                        "operation": "set",

                        "expression": "to_string(cf.bot_management.score)"

                    }

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "<RULESET_ID>",

    "name": "Zone-level Late Transform Ruleset",

    "description": "Zone-level ruleset that will execute Late Transform Rules.",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "ref": "add_header_bot_score",

        "id": "<RULE_ID>",

        "version": "1",

        "action": "rewrite",

        "action_parameters": {

          "headers": {

            "X-Bot-Score": {

              "operation": "set",

              "expression": "to_string(cf.bot_management.score)"

            }

          }

        },

        "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

        "description": "My first request header transform rule",

        "last_updated": "2021-04-14T14:42:04.219025Z",

        "ref": "<RULE_REF>"

      }

    ],

    "last_updated": "2021-04-14T14:42:04.219025Z",

    "phase": "http_request_late_transform"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

Example: Remove an HTTP request header

The following example sets the rules of an existing phase ruleset (`$RULESET_ID`) to a single request header transform rule — removing an HTTP request header — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/). The response will contain the complete definition of the ruleset you updated.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "remove_header_cf_connecting_ip",

            "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

            "description": "My first request header transform rule",

            "action": "rewrite",

            "action_parameters": {

                "headers": {

                    "cf-connecting-ip": {

                        "operation": "remove"

                    }

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "<RULESET_ID>",

    "name": "Zone-level Late Transform Ruleset",

    "description": "Zone-level ruleset that will execute Late Transform Rules.",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "ref": "remove_header_cf_connecting_ip",

        "id": "<RULE_ID>",

        "version": "1",

        "action": "rewrite",

        "action_parameters": {

          "headers": {

            "cf-connecting-ip": {

              "operation": "remove"

            }

          }

        },

        "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

        "description": "My first request header transform rule",

        "last_updated": "2021-04-14T14:42:04.219025Z",

        "ref": "<RULE_REF>"

      }

    ],

    "last_updated": "2021-04-14T14:42:04.219025Z",

    "phase": "http_request_late_transform"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

---

## Required API token permissions

The API token used in API requests to manage Request Header Transform Rules must have at least the following permissions:

* _Transform Rules_ \> _Edit_
* _Account Rulesets_ \> _Read_

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/request-header-modification/","name":"Request Header Transform Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/request-header-modification/create-api/","name":"Create a request header transform rule via API"}}]}
```

---

---
title: Create a request header transform rule in the dashboard
description: Refer to the Rules examples gallery for examples of rule definitions.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/request-header-modification/create-dashboard.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a request header transform rule in the dashboard

Refer to the [Rules examples gallery](https://developers.cloudflare.com/rules/transform/examples/?operation=Request+modification) for examples of rule definitions.

To create a rule:

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Create rule** \> **Request Header Transform Rule**.
3. (Optional) Select one of the rule templates that address common use cases. Then, review and adjust the proposed rule configuration.
4. Enter a descriptive name for the rule in **Rule name**.
5. Under **When incoming requests match**, select if you wish to apply the rule to all incoming requests or only to requests that match a custom filter expression.
6. (Optional) To define a custom expression, use the Expression Builder (specifying one or more values for **Field**, **Operator**, and **Value**) or manually enter an expression using the Expression Editor. For more information, refer to [Edit expressions in the dashboard](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/).  
Note  
Check the [available fields and functions](https://developers.cloudflare.com/rules/transform/request-header-modification/reference/fields-functions/).
7. For **Modify request header**, select one of the following options:  
   * _Set static_ — Sets the value of an HTTP request header to a static string value. Overrides the value of an existing header with the same name or adds a new header if it does not exist.  
   * _Set dynamic_ — Sets the value of an HTTP request header according to the provided expression. Overrides the value of an existing header with the same name or adds a new header if it does not exist.  
   * _Remove_ — Removes the HTTP request header with the provided name, if it exists.
8. Enter the name of the HTTP request header to modify in **Header name** and the static value or expression in **Value**, if you are setting the header value.
9. To modify another HTTP request header in the same rule, select **Set new header**. You can modify up to 30 HTTP request headers in a single rule.  
The following example includes the modification of three headers:  
![Example configuration performing three request header modifications: set a dynamic header value, set a static header value, and remove an existing header.](https://developers.cloudflare.com/_astro/request-header-modification-example.CKUUJ7cw_2iC6Rs.webp)
10. To save and deploy your rule, select **Deploy**. If you are not ready to deploy your rule, select **Save as Draft**.  
If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to [Troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/#this-rule-may-not-apply-to-your-traffic) for more information.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/request-header-modification/","name":"Request Header Transform Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/request-header-modification/create-dashboard/","name":"Create a request header transform rule in the dashboard"}}]}
```

---

---
title: Create a rule using Terraform
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/request-header-modification/link-create-terraform.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a rule using Terraform

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/request-header-modification/","name":"Request Header Transform Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/request-header-modification/link-create-terraform/","name":"Create a rule using Terraform"}}]}
```

---

---
title: Available fields and functions
description: The available fields when setting an HTTP request header value using an expression are the following:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/request-header-modification/reference/fields-functions.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Available fields and functions

The available fields when setting an HTTP request header value using an expression are the following:

* `cf.bot_management.*`
* `cf.bot_detection.js_check_score`
* `cf.client.bot`
* `cf.threat_score`
* `cf.verified_bot_category`
* `cf.edge.server_ip`
* `cf.edge.server_port`
* `cf.edge.client_port`
* `cf.hostname.metadata`
* `cf.zone.name`
* `cf.metal.id`
* `cf.random_seed`
* `cf.ray_id`
* `cf.tls_version`
* `cf.tls_cipher`
* `cf.tls_client_hello_length`
* `cf.tls_client_random`
* `cf.tls_client_extensions_sha1`
* `cf.tls_client_extensions_sha1_le`
* `cf.tls_client_ciphers_sha1`
* `cf.tls_client_auth.*`
* `http.cookie`
* `http.host`
* `http.referer`
* `http.request.headers`
* `http.request.headers.*`
* `http.request.accepted_languages`
* `http.request.method`
* `http.request.timestamp.sec`
* `http.request.timestamp.msec`
* `http.request.full_uri`
* `http.request.uri`
* `http.request.uri.*`
* `http.request.version`
* `raw.http.request.full_uri`
* `raw.http.request.uri`
* `raw.http.request.uri.*`
* `raw.http.request.headers`
* `raw.http.request.headers.*`
* `http.user_agent`
* `http.x_forwarded_for`
* `ip.src`
* `ip.src.lat`
* `ip.src.lon`
* `ip.src.asnum`
* `ip.src.city`
* `ip.src.country`
* `ip.src.continent`
* `ip.src.metro_code`
* `ip.src.postal_code`
* `ip.src.region`
* `ip.src.region_code`
* `ip.src.is_in_european_union`
* `ip.src.subdivision_1_iso_code`
* `ip.src.subdivision_2_iso_code`
* `ssl`
* `http.request.jwt.claims`
* `http.request.jwt.claims.*`
* `cf.sequence.current_op`
* `cf.sequence.msec_since_op`
* `cf.sequence.previous_ops`
* `cf.waf.auth_detected`
* `cf.waf.credential_check.*`
* `cf.waf.score`
* `cf.waf.score.*`
* `cf.worker.upstream_zone`

Refer to [Fields](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/) for reference information on these fields.

Important

* To obtain the value of an HTTP header using the [http.request.headers](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.request.headers/) field, specify the header name in **lowercase**. For example, to get the first value of the `Accept-Encoding` request header in an expression, use: `http.request.headers["accept-encoding"][0]`.
* Use the `to_string()` function to get the string representation of a non-string value like an Integer value. For example, `to_string(cf.bot_management.score)`.

For information on the available functions, refer to [Functions](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/request-header-modification/","name":"Request Header Transform Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/request-header-modification/reference/","name":"Reference"}},{"@type":"ListItem","position":6,"item":{"@id":"/rules/transform/request-header-modification/reference/fields-functions/","name":"Available fields and functions"}}]}
```

---

---
title: Format of HTTP request header names and values
description: The name of the HTTP request header you want to set or remove can only contain:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/request-header-modification/reference/header-format.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Format of HTTP request header names and values

The **name** of the HTTP request header you want to set or remove can only contain:

* Alphanumeric characters: `a`\-`z`, `A`\-`Z`, and `0`\-`9`
* The following special characters: `-` and `_`

The **value** of the HTTP request header you want to set can only contain:

* Alphanumeric characters: `a`\-`z`, `A`\-`Z`, and `0`\-`9`
* The following special characters: `` _ :;.,\/"'?!(){}[]@<>=-+*#$&`|~^% ``

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/request-header-modification/","name":"Request Header Transform Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/request-header-modification/reference/","name":"Reference"}},{"@type":"ListItem","position":6,"item":{"@id":"/rules/transform/request-header-modification/reference/header-format/","name":"Format of HTTP request header names and values"}}]}
```

---

---
title: API parameter reference
description: To set an HTTP request header via API, set the following parameters in the action_parameters field:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/request-header-modification/reference/parameters.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# API parameter reference

To set an HTTP request header via API, set the following parameters in the `action_parameters` field:

* **operation**: `set`
* Include one of the following parameters to define a static or dynamic value:  
   * **value**: Specifies a static value for the HTTP request header.  
   * **expression**: Specifies the expression that defines a value for the HTTP request header.

To remove an HTTP request header via API, set the following parameter in the `action_parameters` field:

* **operation**: `remove`

For step-by-step instructions, refer to [Create a request header transform rule via API](https://developers.cloudflare.com/rules/transform/request-header-modification/create-api/).

## Static header value parameters

The full syntax of the `action_parameters` field to define a static HTTP request header value is the following:

```

"action_parameters": {

  "headers": {

    "<HEADER_NAME>": {

      "operation": "set",

      "value": "<URI_PATH_VALUE>"

    }

  }

}


```

## Dynamic header value parameters

The full syntax of the `action_parameters` field to define a dynamic HTTP request header value using an expression is the following:

```

"action_parameters": {

  "headers": {

    "<HEADER_NAME>": {

      "operation": "set",

      "expression": "<EXPRESSION>"

    }

  }

}


```

Note

Check the [available fields and functions](https://developers.cloudflare.com/rules/transform/request-header-modification/reference/fields-functions/) you can use in an expression.

## Header removal parameters

The full syntax of the `action_parameters` field to remove an HTTP request header is the following:

```

"action_parameters": {

  "headers": {

    "<HEADER_NAME>": {

      "operation": "remove"

    }

  }

}


```

## Different header modifications in the same rule

The same rule can modify different HTTP request headers using different operations (set or remove a header). For example, a single rule can set the value of a header and remove a different header. The syntax of such a rule could be the following:

```

"action_parameters": {

  "headers": {

    "<HEADER_NAME_1>": {

      "operation": "set",

      "value": "<HEADER_VALUE_1>"

    },

    "<HEADER_NAME_2>": {

      "operation": "remove"

    }

  }

}


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/request-header-modification/","name":"Request Header Transform Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/request-header-modification/reference/","name":"Reference"}},{"@type":"ListItem","position":6,"item":{"@id":"/rules/transform/request-header-modification/reference/parameters/","name":"API parameter reference"}}]}
```

---

---
title: Response Header Transform Rules
description: Use Response Header Transform Rules to manipulate the headers of HTTP responses sent to website visitors.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/response-header-modification/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Response Header Transform Rules

Use Response Header Transform Rules to manipulate the headers of HTTP responses sent to website visitors.

flowchart LR
accTitle: Header modifications diagram
accDescr: Header transform rules can change the headers sent to your origin server (request header modifications) or sent your your website visitors (response header modifications).

A[Visitor]
B((Cloudflare))
C[(Origin server)]

A -.-> B -. "Includes request<br> header modifications" .-> C
C -.-> B == "Includes response<br> header modifications" ==> A

style A stroke-width: 2px
style B stroke: orange,fill: orange,color: black
linkStyle 0,1,2 stroke-width: 1px
linkStyle 3 stroke-width: 3px

  
To modify HTTP headers in the **request** sent to your origin server, refer to [Request Header Transform Rules](https://developers.cloudflare.com/rules/transform/request-header-modification/).

Through Response Header Transform Rules you can:

* Set the value of an HTTP response header to a literal string value, overwriting its previous value or adding a new header to the response if it does not exist.
* Set the value of an HTTP response header according to an expression, overwriting its previous value or adding a new header to the response if it does not exist.
* Add a new HTTP response header with a literal string value without removing any existing headers with the same name.
* Add a new HTTP response header according to an expression without removing any existing headers with the same name.
* Remove an HTTP header from the response.

You can create a response header transform rule [in the dashboard](https://developers.cloudflare.com/rules/transform/response-header-modification/create-dashboard/), [via API](https://developers.cloudflare.com/rules/transform/response-header-modification/create-api/), or [using Terraform](https://developers.cloudflare.com/terraform/additional-configurations/transform-rules/#create-a-response-header-transform-rule).

For more complex response header modifications, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

## Important remarks

* The response header values are calculated using the field values from the corresponding HTTP request. For example, the value of `ip.src.country` will be the country of the website visitor, not the origin where the response was sent from.
* You cannot add, modify, or remove HTTP response headers whose name starts with `cf-` or `x-cf-`.
* You cannot modify the value of certain headers such as `server`, `eh-cache-tag`, or `eh-cdn-cache-control`.
* Currently you cannot reference [IP lists](https://developers.cloudflare.com/waf/tools/lists/custom-lists/#ip-lists) in expressions of Response Header Transform Rules.
* The HTTP response header removal operation will remove all response headers with the provided name.
* If you change the value of an existing HTTP response header using an expression that evaluates to an empty string (`""`) or an undefined value, the HTTP response header is **removed**.
* Currently, there is a limited number of HTTP response headers that you cannot change. Cloudflare may remove restrictions for some of these HTTP response headers when presented with valid use cases. [Create a post in the community ↗](https://community.cloudflare.com) for consideration.
* Response header transform rules will also apply to default Cloudflare error pages and [Custom Errors](https://developers.cloudflare.com/rules/custom-errors/).
* Modifying `cache-control`, `CDN-Cache-Control`, or `Cloudflare-CDN-Cache-Control` headers will not change the way Cloudflare caches an object. Instead, you should create a [Cache Rule](https://developers.cloudflare.com/cache/how-to/cache-rules/).
* To add a `set-cookie` header to the response, make sure you use one of the _Add static_/_Add dynamic_ operations instead of _Set static_/_Set dynamic_. Using one of the _Set_ operations will remove any `set-cookie` headers already in the response, including those added by other Cloudflare products such as Bot Management.
* Response header transform rules run in order, and later rules can overwrite changes done by previous rules.
* The values of request and response fields are immutable within each [phase](https://developers.cloudflare.com/ruleset-engine/about/phases/), such as the `http_response_headers_transform` phase where response header transform rules are defined. This means that later response header transform rules will not match based on changes done by previous response header transform rules. Refer to [Field values during rule evaluation](https://developers.cloudflare.com/ruleset-engine/about/rules/#field-values-during-rule-evaluation) for more information.

## Troubleshooting

When troubleshooting Response Header Transform Rules, use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to determine if a rule is triggering for a specific URL.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/response-header-modification/","name":"Response Header Transform Rules"}}]}
```

---

---
title: Create a response header transform rule via API
description: Use the Rulesets API to create Response Header Transform Rules via API. Refer to the Rules examples gallery for common use cases.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/response-header-modification/create-api.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a response header transform rule via API

Use the [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/) to create Response Header Transform Rules via API. Refer to the [Rules examples gallery](https://developers.cloudflare.com/rules/transform/examples/?operation=Response+modification) for common use cases.

If you are using Terraform, refer to [Transform Rules configuration using Terraform](https://developers.cloudflare.com/terraform/additional-configurations/transform-rules/#create-a-response-header-transform-rule).

## Basic rule settings

When creating a response header transform rule via API, make sure you:

* Set the rule action to `rewrite`.
* Define the [header modification parameters](https://developers.cloudflare.com/rules/transform/request-header-modification/reference/parameters/) in the `action_parameters` field according to the operation to perform (set, add, or remove header).
* Deploy the rule to the `http_response_headers_transform` phase at the zone level.

## Procedure

Follow this workflow to create a response header transform rule for a given zone via API:

1. Use the [List zone rulesets](https://developers.cloudflare.com/api/resources/rulesets/methods/list/) operation to check if there is already a ruleset for the `http_response_headers_transform` phase at the zone level.
2. If the phase ruleset does not exist, create it using the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) operation. In the new ruleset properties, set the following values:  
   * **kind**: `zone`  
   * **phase**: `http_response_headers_transform`
3. Use the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation to add a response header transform rule to the list of ruleset rules. Alternatively, include the rule in the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) request mentioned in the previous step.

Make sure your API token has the [required permissions](#required-api-token-permissions) to perform the API operations.

## Example requests

Example: Set an HTTP response header to a static value

The following example configures the rules of an existing phase ruleset (`$RULESET_ID`) to a single response header transform rule — setting an HTTP response header to a static value — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation. The response will contain the complete definition of the ruleset you updated.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "set_resp_header_source",

            "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

            "description": "My first response header transform rule",

            "action": "rewrite",

            "action_parameters": {

                "headers": {

                    "X-Source": {

                        "operation": "set",

                        "value": "Cloudflare"

                    }

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "<RULESET_ID>",

    "name": "Zone-level Response Headers Transform Ruleset",

    "description": "Zone-level ruleset that will execute Response Header Transform Rules.",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "ref": "set_resp_header_source",

        "id": "<RULE_ID>",

        "version": "1",

        "action": "rewrite",

        "action_parameters": {

          "headers": {

            "X-Source": {

              "operation": "set",

              "value": "Cloudflare"

            }

          }

        },

        "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

        "description": "My first response header transform rule",

        "last_updated": "2021-04-14T14:42:04.219025Z",

        "ref": "<RULE_REF>"

      }

    ],

    "last_updated": "2021-04-14T14:42:04.219025Z",

    "phase": "http_response_headers_transform"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

Example: Set an HTTP response header to a dynamic value

The following example configures the rules of an existing phase ruleset (`$RULESET_ID`) to a single response header transform rule — setting an HTTP response header to a dynamic value — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation. The response will contain the complete definition of the ruleset you updated.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "set_resp_header_bot_score",

            "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

            "description": "My first response header transform rule",

            "action": "rewrite",

            "action_parameters": {

                "headers": {

                    "X-Bot-Score": {

                        "operation": "set",

                        "expression": "to_string(cf.bot_management.score)"

                    }

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "<RULESET_ID>",

    "name": "Zone-level Response Headers Transform Ruleset",

    "description": "Zone-level ruleset that will execute Response Header Transform Rules.",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "ref": "set_resp_header_bot_score",

        "id": "<RULE_ID>",

        "version": "1",

        "action": "rewrite",

        "action_parameters": {

          "headers": {

            "X-Bot-Score": {

              "operation": "set",

              "expression": "to_string(cf.bot_management.score)"

            }

          }

        },

        "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

        "description": "My first response header transform rule",

        "last_updated": "2021-04-14T14:42:04.219025Z",

        "ref": "<RULE_REF>"

      }

    ],

    "last_updated": "2021-04-14T14:42:04.219025Z",

    "phase": "http_response_headers_transform"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

Example: Add a `set-cookie` HTTP response header with a static value

The following example configures the rules of an existing phase ruleset (`$RULESET_ID`) to a single response header transform rule — adding a `set-cookie` HTTP response header with a static value — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation. By configuring the rule with the `add` operation you will keep any existing `set-cookie` headers that may already exist in the response. The response will contain the complete definition of the ruleset you updated.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "add_resp_header_set_mycookie",

            "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

            "description": "My first response header transform rule",

            "action": "rewrite",

            "action_parameters": {

                "headers": {

                    "set-cookie": {

                        "operation": "add",

                        "value": "mycookie=custom_value"

                    }

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "<RULESET_ID>",

    "name": "Zone-level Response Headers Transform Ruleset",

    "description": "Zone-level ruleset that will execute Response Header Transform Rules.",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "ref": "add_resp_header_set_mycookie",

        "id": "<RULE_ID>",

        "version": "1",

        "action": "rewrite",

        "action_parameters": {

          "headers": {

            "set-cookie": {

              "operation": "add",

              "value": "mycookie=custom_value"

            }

          }

        },

        "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

        "description": "My first response header transform rule",

        "last_updated": "2021-04-14T14:42:04.219025Z",

        "ref": "<RULE_REF>"

      }

    ],

    "last_updated": "2021-04-14T14:42:04.219025Z",

    "phase": "http_response_headers_transform"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

Example: Remove an HTTP response header

The following example sets the rules of an existing phase ruleset (`$RULESET_ID`) to a single response header transform rule — removing an HTTP response header — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation. The response will contain the complete definition of the ruleset you updated.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "remove_resp_header_cf_connecting_ip",

            "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

            "description": "My first response header transform rule",

            "action": "rewrite",

            "action_parameters": {

                "headers": {

                    "cf-connecting-ip": {

                        "operation": "remove"

                    }

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "<RULESET_ID>",

    "name": "Zone-level Response Headers Transform Ruleset",

    "description": "Zone-level ruleset that will execute Response Header Transform Rules.",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "ref": "remove_resp_header_cf_connecting_ip",

        "id": "<RULE_ID>",

        "version": "1",

        "action": "rewrite",

        "action_parameters": {

          "headers": {

            "cf-connecting-ip": {

              "operation": "remove"

            }

          }

        },

        "expression": "(starts_with(http.request.uri.path, \"/en/\"))",

        "description": "My first response header transform rule",

        "last_updated": "2021-04-14T14:42:04.219025Z",

        "ref": "<RULE_REF>"

      }

    ],

    "last_updated": "2021-04-14T14:42:04.219025Z",

    "phase": "http_response_headers_transform"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

---

## Required API token permissions

The API token used in API requests to manage Response Header Transform Rules must have at least the following permissions:

* _Transform Rules_ \> _Edit_
* _Account Rulesets_ \> _Read_

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/response-header-modification/","name":"Response Header Transform Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/response-header-modification/create-api/","name":"Create a response header transform rule via API"}}]}
```

---

---
title: Create a response header transform rule in the dashboard
description: Refer to the Rules examples gallery for examples of rule definitions.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/response-header-modification/create-dashboard.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a response header transform rule in the dashboard

Refer to the [Rules examples gallery](https://developers.cloudflare.com/rules/transform/examples/?operation=Response+modification) for examples of rule definitions.

To create a rule:

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Create rule** \> **Response Header Transform Rule**.
3. (Optional) Select one of the rule templates that address common use cases. Then, review and adjust the proposed rule configuration.
4. Enter a descriptive name for the rule in **Rule name**.
5. Under **When incoming requests match**, select if you wish to apply the rule to all incoming requests or only to requests that match a custom filter expression.
6. (Optional) To define a custom expression, use the Expression Builder (specifying one or more values for **Field**, **Operator**, and **Value**) or manually enter an expression using the Expression Editor. For more information, refer to [Edit expressions in the dashboard](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/).  
Note  
Check the [available fields and functions](https://developers.cloudflare.com/rules/transform/response-header-modification/reference/fields-functions/).
7. For **Modify response header**, select one of the following operations:  
   * _Add static_ — Adds an HTTP response header with a static string value. This operation will not remove any existing response headers with the same name.  
   * _Add dynamic_ — Adds an HTTP response header according to the provided expression. This operation will not remove any existing response headers with the same name.  
   * _Set static_ — Sets the value of an HTTP response header to a static string value. Overrides the value of any existing headers with the same name or adds a new header if it does not exist.  
   * _Set dynamic_ — Sets the value of an HTTP response header according to the provided expression. Overrides the value of any existing headers with the same name or adds a new header if it does not exist.  
   * _Remove_ — Removes the HTTP response header with the provided name, if it exists.
8. Enter the name of the HTTP response header to modify in **Header name** and the static value or expression in **Value**, if you are setting the header value.
9. To modify another HTTP response header in the same rule, select **Set new header**. You can modify up to 30 HTTP response headers in a single rule.  
The following example includes the modification of three response headers:  
![Example configuration performing three response header modifications: set a dynamic header value, set a static header value, and remove an existing header.](https://developers.cloudflare.com/_astro/response-header-modification-example.DTGup8MQ_1pIQOW.webp)
10. To save and deploy your rule, select **Deploy**. If you are not ready to deploy your rule, select **Save as Draft**.  
If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to [Troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/#this-rule-may-not-apply-to-your-traffic) for more information.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/response-header-modification/","name":"Response Header Transform Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/response-header-modification/create-dashboard/","name":"Create a response header transform rule in the dashboard"}}]}
```

---

---
title: Create a rule using Terraform
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/response-header-modification/link-create-terraform.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a rule using Terraform

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/response-header-modification/","name":"Response Header Transform Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/response-header-modification/link-create-terraform/","name":"Create a rule using Terraform"}}]}
```

---

---
title: Available fields and functions
description: The available fields when setting an HTTP response header value using an expression are the following:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/response-header-modification/reference/fields-functions.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Available fields and functions

The available fields when setting an HTTP response header value using an expression are the following:

* `cf.bot_management.*`
* `cf.bot_detection.js_check_score`
* `cf.client.bot`
* `cf.threat_score`
* `cf.verified_bot_category`
* `cf.edge.server_ip`
* `cf.edge.server_port`
* `cf.edge.client_port`
* `cf.hostname.metadata`
* `cf.zone.name`
* `cf.metal.id`
* `cf.random_seed`
* `cf.ray_id`
* `cf.tls_version`
* `cf.tls_cipher`
* `cf.tls_client_hello_length`
* `cf.tls_client_random`
* `cf.tls_client_extensions_sha1`
* `cf.tls_client_extensions_sha1_le`
* `cf.tls_client_ciphers_sha1`
* `cf.tls_client_auth.*`
* `http.cookie`
* `http.host`
* `http.referer`
* `http.request.headers`
* `http.request.headers.*`
* `http.request.accepted_languages`
* `http.request.method`
* `http.request.timestamp.sec`
* `http.request.timestamp.msec`
* `http.request.full_uri`
* `http.request.uri`
* `http.request.uri.*`
* `http.request.version`
* `raw.http.request.full_uri`
* `raw.http.request.uri`
* `raw.http.request.uri.*`
* `raw.http.request.headers`
* `raw.http.request.headers.*`
* `http.user_agent`
* `http.x_forwarded_for`
* `ip.src`
* `ip.src.lat`
* `ip.src.lon`
* `ip.src.asnum`
* `ip.src.city`
* `ip.src.country`
* `ip.src.continent`
* `ip.src.metro_code`
* `ip.src.postal_code`
* `ip.src.region`
* `ip.src.region_code`
* `ip.src.is_in_european_union`
* `ip.src.subdivision_1_iso_code`
* `ip.src.subdivision_2_iso_code`
* `ssl`
* `http.response.code`
* `http.response.headers`
* `http.response.headers.*`
* `http.response.content_type.media_type`
* `cf.response.1xxx_code`
* `cf.response.error_type`

Refer to [Fields](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/) for reference information on these fields.

Important

* To obtain the value of an HTTP header using the [http.request.headers](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.request.headers/) or [http.response.headers](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.response.headers/) field, specify the header name in **lowercase**. For example, to get the first value of the `Accept-Encoding` request header in an expression, use: `http.request.headers["accept-encoding"][0]`.
* Use the `to_string()` function to get the string representation of a non-string value like an Integer value. For example, `to_string(cf.bot_management.score)`.

For information on the available functions, refer to [Functions](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/response-header-modification/","name":"Response Header Transform Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/response-header-modification/reference/","name":"Reference"}},{"@type":"ListItem","position":6,"item":{"@id":"/rules/transform/response-header-modification/reference/fields-functions/","name":"Available fields and functions"}}]}
```

---

---
title: Format of HTTP response header names and values
description: The name of the HTTP response header you want to set or remove can only contain:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/response-header-modification/reference/header-format.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Format of HTTP response header names and values

The **name** of the HTTP response header you want to set or remove can only contain:

* Alphanumeric characters: `a`\-`z`, `A`\-`Z`, and `0`\-`9`
* The following special characters: `-` and `_`

The **value** of the HTTP response header you want to set can only contain:

* Alphanumeric characters: `a`\-`z`, `A`\-`Z`, and `0`\-`9`
* The following special characters: `` _ :;.,\/"'?!(){}[]@<>=-+*#$&`|~^% ``

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/response-header-modification/","name":"Response Header Transform Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/response-header-modification/reference/","name":"Reference"}},{"@type":"ListItem","position":6,"item":{"@id":"/rules/transform/response-header-modification/reference/header-format/","name":"Format of HTTP response header names and values"}}]}
```

---

---
title: API parameter reference
description: To set an HTTP response header, overwriting any headers with the same name, use the following parameters in the action_parameters field:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/response-header-modification/reference/parameters.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# API parameter reference

To set an HTTP response header, overwriting any headers with the same name, use the following parameters in the `action_parameters` field:

* **operation**: `set`
* Include one of the following parameters to define a static or dynamic value:  
   * **value**: Specifies a static value for the HTTP response header.  
   * **expression**: Specifies the expression that defines a value for the HTTP response header.

To add an HTTP response header, keeping any existing headers with the same name, use the following parameters in the `action_parameters` field:

* **operation**: `add`
* Include one of the following parameters to define a static or dynamic value:  
   * **value**: Specifies a static value for the HTTP response header.  
   * **expression**: Specifies the expression that defines a value for the HTTP response header.

To remove an HTTP response header, set the following parameter in the `action_parameters` field:

* **operation**: `remove`

## Static header value parameters

The full syntax of the `action_parameters` field to define a static HTTP response header value is the following:

```

"action_parameters": {

  "headers": {

    "<HEADER_NAME>": {

      "operation": "<set|add>",

      "value": "<URI_PATH_VALUE>"

    }

  }

}


```

## Dynamic header value parameters

The full syntax of the `action_parameters` field to define a dynamic HTTP response header value using an expression is the following:

```

"action_parameters": {

  "headers": {

    "<HEADER_NAME>": {

      "operation": "<set|add>",

      "expression": "<EXPRESSION>"

    }

  }

}


```

Note

Check the [available fields and functions](https://developers.cloudflare.com/rules/transform/request-header-modification/reference/fields-functions/) you can use in an expression.

## Header removal parameters

The full syntax of the `action_parameters` field to remove an HTTP response header is the following:

```

"action_parameters": {

  "headers": {

    "<HEADER_NAME>": {

      "operation": "remove"

    }

  }

}


```

## Different header modifications in the same rule

The same rule can modify different HTTP response headers using different operations. For example, a single rule can set the value of a header and remove a different header. The syntax of such a rule could be the following:

```

"action_parameters": {

  "headers": {

    "<HEADER_NAME_1>": {

      "operation": "set",

      "value": "<HEADER_VALUE_1>"

    },

    "<HEADER_NAME_2>": {

      "operation": "remove"

    }

  }

}


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/response-header-modification/","name":"Response Header Transform Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/response-header-modification/reference/","name":"Reference"}},{"@type":"ListItem","position":6,"item":{"@id":"/rules/transform/response-header-modification/reference/parameters/","name":"API parameter reference"}}]}
```

---

---
title: Troubleshoot Transform Rules
description: When troubleshooting a rule configuration, review the Transform Rules evaluation section to understand how and when your Transform Rule is evaluated for each request.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/troubleshooting.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Troubleshoot Transform Rules

When troubleshooting a rule configuration, review the [Transform Rules evaluation](https://developers.cloudflare.com/rules/transform/#transform-rules-evaluation) section to understand how and when your Transform Rule is evaluated for each request.

For more information on runtime errors related to Transform Rules configuration, refer to [Cloudflare 1xxx errors](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/).

## Why do I not see my request header modifications?

Transform Rules performing request header modifications affect the HTTP headers sent by Cloudflare's network to your origin server. You will not find these headers in your browser request or response data, which can make it difficult to tell if the rule is working as intended.

To check if a request header transform rule is taking effect, you can check the logs on your origin server or use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to check that the rule is matching traffic correctly. Since [Cloudflare Logpush](https://developers.cloudflare.com/logs/logpush/) only logs original HTTP request/response headers, Logpush logs will not include any header transformations done via Transform Rules.

To add HTTP headers that website visitors will receive in their browsers, you must [modify the response headers](https://developers.cloudflare.com/rules/transform/response-header-modification/) instead.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/troubleshooting/","name":"Troubleshoot Transform Rules"}}]}
```

---

---
title: URL Rewrite Rules
description: You can manipulate the URL of a request through different operations, namely rewrites and redirects:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/url-rewrite/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# URL Rewrite Rules

You can manipulate the URL of a request through different operations, namely rewrites and redirects:

* **URL rewrite**: A server-side operation that converts a source URL into a target URL. It occurs before a web server has fully processed a request. A rewrite is not visible to website visitors, since the URL displayed in the browser does not change. Configure URL Rewrite Rules to perform rewrites on the Cloudflare global network without reaching your web server.
* **URL redirect**: A client-side operation that converts a source URL into a target URL. It occurs after the web server has loaded the initial URL. In this case, a website visitor can notice the URL changing when the redirect occurs. Refer to [Redirects](https://developers.cloudflare.com/rules/url-forwarding/) to learn more about configuring redirects.

Use a URL rewrite rule to return the content of a URL while displaying a different URL in the browser. You can rewrite the URI path, the query string, or both.

Warning

You cannot rewrite the hostname using a URL rewrite rule. To rewrite the hostname, use an [origin rule](https://developers.cloudflare.com/rules/origin-rules/features/#dns-record).

For more complex rewrite logic, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

## Static and dynamic rewrites

URL Rewrite Rules can perform static or dynamic rewrites:

* **Static rewrite**: Replaces a given part of a request URL (path or query string) with a static string.
* **Dynamic rewrite**: Supports more advanced scenarios where you use a rewrite expression to define the resulting path or query string.

Create URL Rewrite Rules [in the dashboard](https://developers.cloudflare.com/rules/transform/url-rewrite/create-dashboard/), [via Cloudflare API](https://developers.cloudflare.com/rules/transform/url-rewrite/create-api/), or [using Terraform](https://developers.cloudflare.com/terraform/additional-configurations/transform-rules/#create-a-url-rewrite-rule).

## Serve images from custom paths

When using Cloudflare Images, you can use URL Rewrite Rules to serve images from a custom path. For more information, refer to [Serve images from custom domains](https://developers.cloudflare.com/images/manage-images/serve-images/serve-from-custom-domains/).

## Troubleshooting

When troubleshooting URL Rewrite Rules, use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to determine if a rule is triggering for a specific URL.

## Important remarks

* URL rewrite rules run in order, and later rules can overwrite changes done by previous rules.
* The values of request and response fields are immutable within each [phase](https://developers.cloudflare.com/ruleset-engine/about/phases/), such as the `http_request_transform` phase where URL rewrite rules are defined. This means that later URL rewrite rules will not match based on changes done by previous URL rewrite rules. Refer to [Field values during rule evaluation](https://developers.cloudflare.com/ruleset-engine/about/rules/#field-values-during-rule-evaluation) for more information.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/url-rewrite/","name":"URL Rewrite Rules"}}]}
```

---

---
title: Create a URL rewrite rule via API
description: Use the Rulesets API to create URL Rewrite Rules via API. Refer to the Rules examples gallery for common use cases.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/url-rewrite/create-api.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a URL rewrite rule via API

Use the [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/) to create URL Rewrite Rules via API. Refer to the [Rules examples gallery](https://developers.cloudflare.com/rules/transform/examples/?operation=Rewrite+URL) for common use cases.

If you are using Terraform, refer to [Transform Rules configuration using Terraform](https://developers.cloudflare.com/terraform/additional-configurations/transform-rules/#create-a-url-rewrite-rule).

## Basic rule settings

When creating a URL rewrite rule via API, make sure you:

* Set the rule action to `rewrite`.
* Define the [URL rewrite parameters](https://developers.cloudflare.com/rules/transform/url-rewrite/reference/parameters/#api-information) in the `action_parameters` field according to the type of URL rewrite (static or dynamic).
* Deploy the rule to the `http_request_transform` phase at the zone level.

## Procedure

Follow this workflow to create a URL rewrite rule for a given zone via API:

1. Use the [List zone rulesets](https://developers.cloudflare.com/api/resources/rulesets/methods/list/) operation to check if there is already a ruleset for the `http_request_transform` phase at the zone level.
2. If the phase ruleset does not exist, create it using the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) operation. In the new ruleset properties, set the following values:  
   * **kind**: `zone`  
   * **phase**: `http_request_transform`
3. Use the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation to add a URL rewrite rule to the list of ruleset rules. Alternatively, include the rule in the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) request mentioned in the previous step.

Make sure your API token has the [required permissions](#required-api-token-permissions) to perform the API operations.

## Example requests

Example: Add a rule that performs a static URL rewrite

The following example sets the rules of an existing phase ruleset (`$RULESET_ID`) to a single URL rewrite rule — performing a static rewrite of the URI path — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation. The response will contain the complete definition of the ruleset you updated.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "rewrite_eu_to_emea",

            "expression": "(http.request.uri.query contains \"eu\")",

            "description": "My first static URL rewrite rule",

            "action": "rewrite",

            "action_parameters": {

                "uri": {

                    "path": {

                        "value": "/emea.html"

                    }

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "ref": "rewrite_eu_to_emea",

    "id": "<RULESET_ID>",

    "name": "Zone-level Transform Ruleset",

    "description": "Zone-level ruleset that will execute Transform Rules.",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "id": "<RULE_ID>",

        "version": "1",

        "action": "rewrite",

        "action_parameters": {

          "uri": {

            "path": {

              "value": "/emea.html"

            }

          }

        },

        "expression": "(http.request.uri.query contains \"eu\")",

        "description": "My first static URL rewrite rule",

        "last_updated": "2021-04-14T14:42:04.219025Z",

        "ref": "<RULE_REF>"

      }

    ],

    "last_updated": "2021-04-14T14:42:04.219025Z",

    "phase": "http_request_transform"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

Example: Add a rule that performs a dynamic URL rewrite

The following example sets the rules of an existing phase ruleset (`$RULESET_ID`) to a single URL rewrite rule — performing a dynamic rewrite of the URI path — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation. The response will contain the complete definition of the ruleset you updated.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "rewrite_2012_to_archive",

            "expression": "starts_with(http.request.uri.path, \"/news/2012/\")",

            "description": "My first dynamic URL rewrite rule",

            "action": "rewrite",

            "action_parameters": {

                "uri": {

                    "path": {

                        "expression": "concat(\"/archive\", http.request.uri.path)"

                    }

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "<RULESET_ID>",

    "name": "Zone-level Transform Ruleset",

    "description": "Zone-level ruleset that will execute Transform Rules.",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "ref": "rewrite_2012_to_archive",

        "id": "<RULE_ID>",

        "version": "1",

        "action": "rewrite",

        "action_parameters": {

          "uri": {

            "path": {

              "expression": "concat(\"/archive\", http.request.uri.path)"

            }

          }

        },

        "expression": "starts_with(http.request.uri.path, \"/news/2012/\")",

        "description": "My first dynamic URL rewrite rule",

        "last_updated": "2021-04-14T14:42:04.219025Z",

        "ref": "<RULE_REF>"

      }

    ],

    "last_updated": "2021-04-14T14:42:04.219025Z",

    "phase": "http_request_transform"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

---

## Required API token permissions

The API token used in API requests to manage URL Rewrite Rules must have at least the following permissions:

* _Account_ \> _Transform Rules_ \> _Edit_
* _Account_ \> _Account Rulesets_ \> _Read_

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/url-rewrite/","name":"URL Rewrite Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/url-rewrite/create-api/","name":"Create a URL rewrite rule via API"}}]}
```

---

---
title: Create a URL rewrite rule in the dashboard
description: Refer to the Rules examples gallery for examples of rule definitions.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/url-rewrite/create-dashboard.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a URL rewrite rule in the dashboard

Refer to the [Rules examples gallery](https://developers.cloudflare.com/rules/transform/examples/?operation=Rewrite+URL) for examples of rule definitions.

To create a rule:

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Create rule** \> **URL Rewrite Rule**.
3. (Optional) Select one of the rule templates that address common use cases. Then, review and adjust the proposed rule configuration.
4. Enter a descriptive name for the rule in **Rule name**.  
![The URL rewrite rule creation page in the Cloudflare dashboard.](https://developers.cloudflare.com/_astro/create-url-rewrite-rule.DIgpB8IB_ZNTjfK.webp)
5. Under **If incoming requests match**, select one of the following options:  
   * **Wildcard pattern**: The rule will only apply to traffic matching the wildcard pattern in **Request URL**. Refer to [Wildcard pattern parameters](#wildcard-pattern-parameters) for details.  
   * **Custom filter expression**: The rule will only apply to traffic matching a custom expression. Define the [rule expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/) to configure which requests should be rewritten. Use either the Expression Builder or the Expression Editor to define the custom expression. For more information, refer to [Edit expressions in the dashboard](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/).  
   Note  
   Check the [fields and functions](https://developers.cloudflare.com/rules/transform/url-rewrite/reference/fields-functions/) you can use in filter expressions of URL rewrite rules.  
   * **All incoming requests**: The rule will apply to all traffic.
6. (Optional) Define the action for your URL rewrite rule by selecting one of the available options displayed as radio buttons, and then a value from the drop-down list, depending on the action:  
   * If you select **Rewrite to** \> _Static_, enter the string that will replace the original URL path (or query string). For example, enter `welcome-gb.html` to rewrite the original URL path to `/welcome-gb.html`.  
   * If you select **Rewrite to** \> _Dynamic_, enter a [rewrite expression](https://developers.cloudflare.com/rules/transform/url-rewrite/reference/fields-functions/#rewrite-expressions) that defines the dynamic URL rewrite to perform.  
   * If you do not want to change the value of a component of the original request (the URL path or the URL query string), choose _Preserve_ for that component.  
For more information, refer to [URL rewrite parameters](https://developers.cloudflare.com/rules/transform/url-rewrite/reference/parameters/).
7. (Optional) Under **Place at**, define where to place the rule in the rules list: first rule in the list, last rule in the list, or in a custom position (after a given rule).
8. To save and deploy your rule, select **Deploy**. If you are not ready to deploy your rule, select **Save as Draft**.  
If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to [Troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/#this-rule-may-not-apply-to-your-traffic) for more information.

## Wildcard pattern parameters

The Cloudflare dashboard offers a simplified user interface for creating URL rewrites based on wildcard matching and replacement. When you select **Wildcard pattern**, you will have the following parameters available:

* **Request URL**: Enter the [wildcard pattern](https://developers.cloudflare.com/ruleset-engine/rules-language/operators/#wildcard-matching) using the asterisk (`*`) character to match multiple requests. For example, `http*://*.example.com/*`.
* **Then rewrite the path and/or query**: Define the [URL rewrite settings](https://developers.cloudflare.com/rules/transform/url-rewrite/reference/parameters/) including:  
   * **Path** \> **Target path**: Enter the URI path to match, which can include wildcards (for example, `/oldpath/*`).  
   * **Path** \> **Rewrite to**: Enter the new URI path. You can use [wildcard replacement](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#wildcard%5Freplace) such as `${1}` and `${2}` to define a dynamic target path (for example, `/newpath/${1}`). Leave this field empty to remove the URI path.  
   * **Query** \> **Target query**: Enter the query string to match, which can include wildcards (for example, `?sort=*`).  
   * **Query** \> **Rewrite to**: Enter the new query string. You can use [wildcard replacement](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#wildcard%5Freplace) such as `${1}` and `${2}` to define a dynamic query string (for example, `?order=${1}`). Leave this field empty to remove the query string.

Refer to [URL rewrite parameters](https://developers.cloudflare.com/rules/transform/url-rewrite/reference/parameters/#wildcard-matching-and-replacement) for the equivalent rule configuration when using the API.

Notes

The **Request URL** value is only used to match the incoming request with a rule. It will not be used for capturing URL patterns for rewrites. If you are matching the URL path or query string in **Target path** or **Target query**, respectively, make sure that the **Request URL** pattern also matches the incoming request, or else the rule will not trigger.

To validate URL rewrite rule matches, use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/). To validate rewritten URLs, check your origin server.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/url-rewrite/","name":"URL Rewrite Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/url-rewrite/create-dashboard/","name":"Create a URL rewrite rule in the dashboard"}}]}
```

---

---
title: Create a rule using Terraform
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/url-rewrite/link-create-terraform.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a rule using Terraform

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/url-rewrite/","name":"URL Rewrite Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/url-rewrite/link-create-terraform/","name":"Create a rule using Terraform"}}]}
```

---

---
title: Available fields and functions
description: A URL rewrite rule filter expression (that is, the expression that defines which incoming requests match the rule) can include the following fields:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/url-rewrite/reference/fields-functions.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Available fields and functions

## Filter expressions

A URL rewrite rule [filter expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/) (that is, the expression that defines which incoming requests match the rule) can include the following fields:

* `cf.edge.server_ip`
* `cf.edge.server_port`
* `cf.edge.client_port`
* `cf.zone.name`
* `cf.metal.id`
* `cf.ray_id`
* `cf.tls_client_auth.*`
* `http.cookie`
* `http.host`
* `http.referer`
* `http.request.headers`
* `http.request.headers.*`
* `http.request.accepted_languages`
* `http.request.method`
* `http.request.timestamp.sec`
* `http.request.timestamp.msec`
* `http.request.full_uri`
* `http.request.uri`
* `http.request.uri.*`
* `http.request.version`
* `raw.http.request.full_uri`
* `raw.http.request.uri`
* `raw.http.request.uri.*`
* `http.user_agent`
* `http.x_forwarded_for`
* `ip.src`
* `ip.src.lat`
* `ip.src.lon`
* `ip.src.asnum`
* `ip.src.city`
* `ip.src.country`
* `ip.src.continent`
* `ip.src.is_in_european_union`
* `ip.src.subdivision_1_iso_code`
* `ip.src.subdivision_2_iso_code`
* `ssl`

Refer to [Fields](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/) for reference information on these fields.

Important

* To obtain the value of an HTTP request header using the [http.request.headers](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.request.headers/) field, specify the header name in **lowercase**. For example, to get the first value of the `Accept-Encoding` request header in an expression, use: `http.request.headers["accept-encoding"][0]`.
* Use the `to_string()` function to get the string representation of a non-string value like an Integer value.

For information on the available functions, refer to [Functions](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/).

## Rewrite expressions

A rewrite expression (that is, the expression that defines the dynamic URL rewrite to perform) can only include the following fields:

* `http.request.uri.*`
* `http.request.headers.*`
* `http.request.accepted_languages`

Refer to the [Fields reference](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/) for more information on these fields.

The [concat()](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#concat), [regex\_replace()](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#regex%5Freplace), and [wildcard\_replace()](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#wildcard%5Freplace) functions can appear only once in a rewrite expression. Additionally, you cannot nest the `regex_replace()` and `wildcard_replace()` functions.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/url-rewrite/","name":"URL Rewrite Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/url-rewrite/reference/","name":"Reference"}},{"@type":"ListItem","position":6,"item":{"@id":"/rules/transform/url-rewrite/reference/fields-functions/","name":"Available fields and functions"}}]}
```

---

---
title: URL rewrite parameters
description: Static and dynamic URL rewrites have different parameters:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/transform/url-rewrite/reference/parameters.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# URL rewrite parameters

Static and dynamic URL rewrites have different parameters:

* A static URL rewrite requires a static value for the target URL.
* A dynamic URL rewrite requires an expression that, when evaluated, will define the target URL.

A URL rewrite with wildcard patterns is a simplified interface in the Cloudflare dashboard for creating dynamic URL rewrites with [wildcard matching and replacement](#wildcard-matching-and-replacement).

The maximum length of all parameter values in a URL rewrite (combined) is 4,096 characters. For example, you could provide a static value (or an expression) for the URI path with 2,048 characters and a static value (or expression) for the query string with 2,048 characters.

## API information

### Static URL rewrites

The full syntax of the `action_parameters` field for a static URL rewrite rule that rewrites both the URI path and the query string is the following:

```

"action_parameters": {

  "uri": {

    "path": {

      "value": "<URI_PATH_VALUE>"

    },

    "query": {

      "value": "<QUERY_STRING_VALUE>"

    }

  }

}


```

If you are only rewriting the URI path or the query string, omit the `query` or `path` parameter, respectively.

### Dynamic URL rewrites

The full syntax of the `action_parameters` field for a dynamic URL rewrite rule that rewrites both the URI path and the query string is the following:

```

"action_parameters": {

  "uri": {

    "path": {

      "expression": "<URI_PATH_EXPRESSION>"

    },

    "query": {

      "expression": "<QUERY_STRING_EXPRESSION>"

    }

  }

}


```

If you are only rewriting the URI path or the query string, omit the `query` or `path` parameter, respectively.

#### Wildcard matching and replacement

The syntax of a dynamic URL rewrite rule that rewrites both the URI path and the query string based on wildcard matching and replacement is the following:

```

{

  "expression": "(http.request.full_uri wildcard r\"<REQUEST_URL>\")",

  "action_parameters": {

    "uri": {

      "path": {

        "expression": "wildcard_replace(http.request.uri.path, r\"<PATH_TARGET_PATH>\", r\"<PATH_REWRITE_TO>\")"

      },

      "query": {

        "expression": "wildcard_replace(http.request.uri.query, r\"<QUERY_TARGET_QUERY>\", r\"<QUERY_REWRITE_TO>\")"

      }

    }

  },

  "action": "rewrite"

  // ...

}


```

The `<REQUEST_URL>`, `<PATH_TARGET_PATH>`, `<PATH_REWRITE_TO>`, `<QUERY_TARGET_QUERY>`, and `<QUERY_REWRITE_TO>` value placeholders correspond to the fields available in the Cloudflare dashboard when you select the **Wildcard pattern** option. For more information, refer to [Wildcard pattern parameters](https://developers.cloudflare.com/rules/transform/url-rewrite/create-dashboard/#wildcard-pattern-parameters).

Note

The `http.request.uri.query` field does not include the `?` delimiter at the beginning, which means that your `<QUERY_TARGET_QUERY>` value should not try to match an initial `?`.

### Different URL rewrite types in the same rule

The same rule can have different types of URL rewrites for the URI path and the query string. For example, a single rule can perform a **dynamic** URL rewrite of the URI path and a **static** URL rewrite of the query string. The syntax of such a rule would be the following:

```

"action_parameters": {

  "uri": {

    "path": {

      "expression": "<URI_PATH_EXPRESSION>"

    },

    "query": {

      "value": "<QUERY_STRING_VALUE>"

    }

  }

}


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/transform/","name":"Transform Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/transform/url-rewrite/","name":"URL Rewrite Rules"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/transform/url-rewrite/reference/","name":"Reference"}},{"@type":"ListItem","position":6,"item":{"@id":"/rules/transform/url-rewrite/reference/parameters/","name":"URL rewrite parameters"}}]}
```

---

---
title: Redirects
description: URL forwarding, also known as URL redirection, navigates the user from a source URL to a target URL with a specific HTTP status code.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Redirects

URL forwarding, also known as URL redirection, navigates the user from a source URL to a target URL with a specific HTTP status code.

Use the following Cloudflare products to perform URL redirects, according to your use case:

* [**Single Redirects**](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/): Allow you to create static or dynamic redirects at the zone level. A simple interface with [wildcard support](https://developers.cloudflare.com/ruleset-engine/rules-language/operators/#wildcard-matching) lets you easily define source and target URL patterns without needing complex functions or regular expressions, efficiently covering thousands of URLs with a single rule.
* [**Bulk Redirects**](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/): Allow you to define a large number of redirects at the account level. These URL redirects are essentially static — they do not support string replacement operations or regular expressions. However, you can configure parameters that affect the redirects' URL matching behavior and their runtime behavior.
* [**Snippets**](https://developers.cloudflare.com/rules/snippets/): Use short pieces of JavaScript code for a more flexible way to define complex redirect functionality. Consider a few [examples](https://developers.cloudflare.com/rules/snippets/examples/?operation=Redirect) to get started.

Note

Single Redirects and Bulk Redirects require that you [proxy the DNS records](https://developers.cloudflare.com/dns/proxy-status/) of your domain (or subdomain) through Cloudflare.

## Redirect Rules templates

Cloudflare provides you with rules templates for common use cases.

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Templates**, and then select one of the available templates.

You can also refer to the [Examples gallery](https://developers.cloudflare.com/rules/examples/) in the developer docs.

## Availability

Single Redirects and Bulk Redirects are available on all Cloudflare plans. The exact quotas and features depend on your plan.

### Bulk redirects

| Free                       | Pro    | Business | Enterprise |           |
| -------------------------- | ------ | -------- | ---------- | --------- |
| Availability               | Yes    | Yes      | Yes        | Yes       |
| Bulk Redirect Rules        | 15     | 15       | 15         | 50        |
| Bulk Redirect Lists        | 5      | 5        | 5          | 25        |
| URL redirects across lists | 10,000 | 25,000   | 50,000     | 1,000,000 |

For _URL redirects across lists_, this table provides the default quota for the Enterprise plan. Bulk Redirects supports several million URL redirects — to get more redirects, contact your account team.

Bulk Redirects features and quotas are per account and they depend on the highest Cloudflare plan on your account.

### Single Redirects

| Free             | Pro | Business | Enterprise |     |
| ---------------- | --- | -------- | ---------- | --- |
| Availability     | Yes | Yes      | Yes        | Yes |
| Number of rules  | 10  | 25       | 50         | 300 |
| Wildcard support | Yes | Yes      | Yes        | Yes |
| Regex support    | No  | No       | Yes        | Yes |

Single Redirects features and quotas are per zone and depend on the zone plan.

## Execution order

The execution order of Rules features is the following:

* [Single Redirects](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/)
* [URL Rewrite Rules](https://developers.cloudflare.com/rules/transform/url-rewrite/)
* [Configuration Rules](https://developers.cloudflare.com/rules/configuration-rules/)
* [Origin Rules](https://developers.cloudflare.com/rules/origin-rules/)
* [Bulk Redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/)
* [Managed Transforms](https://developers.cloudflare.com/rules/transform/managed-transforms/)
* [Request Header Transform Rules](https://developers.cloudflare.com/rules/transform/request-header-modification/)
* [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/)
* [Snippets](https://developers.cloudflare.com/rules/snippets/)
* [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/)

The different types of rules listed above will take precedence over [Page Rules](https://developers.cloudflare.com/rules/page-rules/). This means that Page Rules will be overridden if there is a match for both Page Rules and the Rules products listed above.

Generally speaking, for [non-terminating actions](https://developers.cloudflare.com/ruleset-engine/rules-language/actions/) the last change made by rules in the same [phase](https://developers.cloudflare.com/ruleset-engine/about/phases/) will win (later rules can overwrite changes done by previous rules). However, for terminating actions (_Block_, _Redirect_, or one of the challenge actions), rule evaluation will stop and the action will be executed immediately.

For example, if multiple rules with the _Redirect_ action match, Cloudflare will always use the URL redirect of the first rule that matches. Also, if you configure URL redirects using different Cloudflare products (Single Redirects and Bulk Redirects), the product executed first will apply, if there is a rule match (in this case, Single Redirects).

Refer to the [Phases list](https://developers.cloudflare.com/ruleset-engine/reference/phases-list/) for the product execution order.

Warning

Using Cloudflare challenges along with Rules features may cause challenge loops. Refer to [Rules troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/) for more information.

## Troubleshooting

When troubleshooting URL redirects, use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to determine if a rule is triggering for a specific URL.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}}]}
```

---

---
title: Bulk Redirects
description: Bulk Redirects allow you to define a large number of URL redirects at the account level. These redirects navigate the user from a source URL to a target URL using a given HTTP status code. URL redirection is also known as URL forwarding.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/bulk-redirects/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Bulk Redirects

Bulk Redirects allow you to define a large number of URL redirects at the account level. These redirects navigate the user from a source URL to a target URL using a given HTTP status code. URL redirection is also known as URL forwarding.

Unlike dynamic URL redirects created in [Single Redirects](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/), Bulk Redirects are essentially static — they do not support string replacement operations or regular expressions. However, you can configure URL redirect parameters that affect their URL matching behavior and their runtime behavior.

For more complex and customized redirect logic, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

---

## Related resources

* [Availability](https://developers.cloudflare.com/rules/url-forwarding/#availability): Information on the Bulk Redirects quotas and features per Cloudflare plan.
* [Execution order](https://developers.cloudflare.com/rules/url-forwarding/#execution-order): Execution order of the different Rules products.
* [Trace a request](https://developers.cloudflare.com/rules/trace-request/): Use Cloudflare Trace to determine if a bulk redirect rule is triggering for a specific URL.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/bulk-redirects/","name":"Bulk Redirects"}}]}
```

---

---
title: Bulk Redirects concepts
description: Bulk Redirects work through a combination of URL redirects, a Bulk Redirect list, and a Bulk Redirect rule.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/bulk-redirects/concepts.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Bulk Redirects concepts

Bulk Redirects involve the following elements:

* **URL redirect**: A simple object with a source URL, a target URL, a status code, and redirect parameters. URL redirects are the list items of Bulk Redirect Lists.
* **Bulk Redirect List**: A list, similar to an IP list, containing one or more URL redirects. To enable all the URL redirects in a Bulk Redirect List, reference the list in a Bulk Redirect Rule. Different Bulk Redirect Rules can reference the same Bulk Redirect List.
* **Bulk Redirect Rule**: A rule powered by the Ruleset Engine, similar to a [Transform Rule](https://developers.cloudflare.com/rules/transform/). A Bulk Redirect Rule has an associated Bulk Redirect List.

A Bulk Redirect Rule enables a Bulk Redirect List, which contains one or more URL redirects.

![Diagram outlining the hierarchy relationship between Bulk Redirect Rules, Bulk Redirect Lists, and URL redirects](https://developers.cloudflare.com/_astro/concepts-diagram.e1YY6ejJ_1XP7bY.webp) 

The following example defines a Bulk Redirect List named `list_b` with two URL redirects:

**`list_b` Bulk Redirect List**

| Source URL               | Target URL               | Status code       |
| ------------------------ | ------------------------ | ----------------- |
| example.com/about        | https://example.com/news | 301 (the default) |
| example.com/new\_feature | https://example.com/soon | 302               |

The following Bulk Redirect Rule, named `Rule 2`, enables the URL redirects in the `list_b` Bulk Redirect List:

**`Rule 2` Bulk Redirect Rule**

* **Rule name**: `Rule 2`
* **Associated list**: `list_b`

## URL redirects

A URL redirect allows you to configure a source URL, a target URL, a status code, and redirect parameters.

When specifying the source URL, use the available redirect parameters instead of wildcards, which are not supported. For example, the **Include subdomains** parameter allows you to configure a single URL redirect that applies both to subdomains (for example, `https://b.example.com` and `https://a.b.example.com`) and to the apex domain (`https://example.com`). Other parameters allow you to specify how the source URL’s path and query string are handled. For more information, refer to [How Bulk Redirects work](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/how-it-works/).

URL redirects are the list items of Bulk Redirect Lists.

## Bulk Redirect Lists

Bulk Redirect Lists allow you to create distinct groups of URL redirects for different purposes. You can use a Bulk Redirect List in one or more Bulk Redirect Rules.

A Bulk Redirect List does not perform any redirects on its own — you must reference the list in a Bulk Redirect Rule to enable the redirects in the list.

A Bulk Redirect List cannot contain several URL redirects with the exact same source URL.

For details on the CSV format for importing items to a Bulk Redirect List, refer to [CSV file format for Bulk Redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/reference/csv-file-format/).

Note

You can only reference Bulk Redirect Lists in Bulk Redirect Rules. Other types of rules powered by the Ruleset Engine do not support Bulk Redirect Lists.

## Bulk Redirect Rules

Bulk Redirect Rules are rules powered by the Ruleset Engine that enable one or more URL redirects through a Bulk Redirect List.

When you configure a Bulk Redirect Rule, you associate a Bulk Redirect List to it, which enables all the URL redirects in that list. You can create a rule for each list, or have many Bulk Redirect Rules referencing the same Bulk Redirect List.

A Bulk Redirect Rule, like all rules powered by the Ruleset Engine, has an action and an expression. Besides these two properties, it also has a name, an optional description, an associated Bulk Redirect List, and a key.

### Expression

The rule expression, or filter expression, specifies the conditions that must be met for the rule to run. By default, all URL redirects of the specified list will apply.

The default expression of a Bulk Redirect Rule is the following:

```

http.request.full_uri in $<LIST_NAME>


```

This expression means that the request URL, after some basic normalization (if [URL normalization](https://developers.cloudflare.com/rules/normalization/) is enabled), should match the source URL of a URL redirect in the list `<LIST_NAME>` for the redirect to be applied.

You can use an expression different from the default one to increase the specificity of URL redirect matches. For example, if you set the expression of a Bulk Redirect Rule to the following expression, there will only be a match for requests coming from the United Kingdom:

```

ip.src.country == "GB" and http.request.full_uri in $<LIST_NAME>


```

For more information on the available fields, refer to [Available fields and functions](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/reference/fields-functions/).

Note

At the left of the `in` operator you can only use fields directly and not values returned by a function. In most situations, you will want to use one of the following fields with the `in` operator:

* `http.request.full_uri`
* `raw.http.request.full_uri`

Refer to the [Fields reference](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/) for more information.

### Key

The rule key is used in combination with the Bulk Redirect List associated with the rule to select the URL redirect to apply.

When there is a match for the rule expression, Cloudflare compares the value of the rule key with the source URL of each URL redirect in the associated Bulk Redirect List, searching for a match.

The key should be either `http.request.full_uri` or `raw.http.request.full_uri`. Use `raw.http.request.full_uri` to compare the URI received by the web server, before normalization, with the source URLs in the Bulk Redirect List.

The URI field used in the key must be the same as the URI field used in the expression. Otherwise, you may have a match for the rule expression, but no match for any of the source URLs in the list. For example, if you set the key to `http.request.full_uri`, the field used in the rule expression must also be `http.request.full_uri`. Conversely, if you set the key to `raw.http.request.full_uri`, the field used in the expression must be `raw.http.request.full_uri`.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/bulk-redirects/","name":"Bulk Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/bulk-redirects/concepts/","name":"Bulk Redirects concepts"}}]}
```

---

---
title: Create Bulk Redirects via API
description: Learn how to create Bulk Redirects using the Cloudflare API.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/bulk-redirects/create-api.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create Bulk Redirects via API

To create Bulk Redirects via API, you must:

1. Create a Bulk Redirect List via API.
2. Add items (URL redirects) to the list created in step 1.
3. Create a Bulk Redirect Rule via API, which enables the list created in step 1.

Note

Bulk Redirects require that the incoming traffic for the hostname referenced in visitors' requests is [proxied by Cloudflare](https://developers.cloudflare.com/dns/proxy-status/).

## 1\. Create a Bulk Redirect List via API

Use the [Create a list](https://developers.cloudflare.com/api/resources/rules/subresources/lists/methods/create/) operation to create a new Bulk Redirect List. The list `kind` must be `redirect`.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Account Filter Lists Edit`

Create a list

```

curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/rules/lists" \

  --request POST \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "name": "my_redirect_list",

    "description": "My redirect list.",

    "kind": "redirect"

  }'


```

```

{

  "result": {

    "id": "f848b6ccb07647749411f504d6f88794",

    "name": "my_redirect_list",

    "description": "My redirect list.",

    "kind": "redirect",

    "num_items": 0,

    "num_referencing_filters": 0,

    "created_on": "2021-10-28T09:11:42Z",

    "modified_on": "2021-10-28T09:11:42Z"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Take note of the list ID — you will need it in the next step.

For more information on list operations, refer to the [Lists API](https://developers.cloudflare.com/waf/tools/lists/lists-api/) documentation.

## 2\. Add items to the list

Use the [Create list items](https://developers.cloudflare.com/api/resources/rules/subresources/lists/subresources/items/methods/create/) operation to add URL redirect items to the list. Enter the list ID from the previous step in the endpoint URL:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Account Filter Lists Edit`

Create list items

```

curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/rules/lists/f848b6ccb07647749411f504d6f88794/items" \

  --request POST \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '[

    {

        "redirect": {

            "source_url": "example.com/blog/",

            "target_url": "https://example.com/blog/latest"

        }

    },

    {

        "redirect": {

            "source_url": "example.net/",

            "target_url": "https://example.net/under-construction.html",

            "status_code": 307

        }

    }

  ]'


```

```

{

  "result": {

    "operation_id": "92558f8b296d4dbe9d0419e0e53f6622"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

This is an asynchronous operation. The response will contain an `operation_id` which you will use to check if the operation completed successfully using the [Get bulk operation status](https://developers.cloudflare.com/api/resources/rules/subresources/lists/subresources/bulk%5Foperations/methods/get/) operation:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Account Filter Lists Edit`
* `Account Filter Lists Read`

Get bulk operation status

```

curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/rules/lists/bulk_operations/92558f8b296d4dbe9d0419e0e53f6622" \

  --request GET \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"


```

Once the operation has completed successfully, the response will be similar to the following:

Response

```

{

  "result": {

    "id": "92558f8b296d4dbe9d0419e0e53f6622",

    "status": "completed",

    "completed": "2021-10-28T09:15:42Z"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

## 3\. Create a Bulk Redirect Rule via API

Since Bulk Redirect Lists are essentially containers of URL redirects, you have to enable the URL redirects in the list by creating a Bulk Redirect Rule.

Add Bulk Redirect Rules to the [entry point ruleset](https://developers.cloudflare.com/ruleset-engine/about/rulesets/#entry-point-ruleset) of the `http_request_redirect` phase at the account level. Refer to the [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/) documentation for more information on [creating a ruleset](https://developers.cloudflare.com/ruleset-engine/rulesets-api/create/) and supplying a list of rules for the ruleset.

A Bulk Redirect Rule must have:

* `action` set to `redirect`
* An `action_parameters` object with additional configuration settings — refer to [Bulk Redirects API JSON objects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/reference/json-objects/#bulk-redirect-rule) for details.

The following request of the [Create an account ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) operation creates a phase entry point ruleset for the `http_request_redirect` phase at the account level, and defines a single redirect rule. Use this operation if you have not created a phase entry point ruleset for the `http_request_redirect` phase yet.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`

Create an account ruleset

```

curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/rulesets" \

  --request POST \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "name": "My redirect ruleset",

    "kind": "root",

    "phase": "http_request_redirect",

    "rules": [

        {

            "ref": "enable_my_redirect_list",

            "expression": "http.request.full_uri in $my_redirect_list",

            "description": "Bulk Redirect rule.",

            "action": "redirect",

            "action_parameters": {

                "from_list": {

                    "name": "my_redirect_list",

                    "key": "http.request.full_uri"

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "528f4f03bf0da53a29907199625867be",

    "name": "My redirect ruleset",

    "kind": "root",

    "version": "1",

    "rules": [

      {

        "ref": "enable_my_redirect_list",

        "id": "8da312df846b4258a05bcd454ea943be",

        "version": "1",

        "expression": "http.request.full_uri in $my_redirect_list",

        "description": "Bulk Redirect rule.",

        "action": "redirect",

        "action_parameters": {

          "from_list": {

            "name": "my_redirect_list",

            "key": "http.request.full_uri"

          }

        },

        "last_updated": "2021-10-28T09:20:42Z"

      }

    ],

    "last_updated": "2021-10-28T09:20:42Z",

    "phase": "http_request_redirect"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

If there is already a phase entry point ruleset for the `http_request_redirect` phase, use the [Update an account ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation instead, like in the following example:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`

Update an account ruleset

```

curl "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "name": "My redirect ruleset",

    "kind": "root",

    "phase": "http_request_redirect",

    "rules": [

        {

            "ref": "eval_redirects_list_1",

            "expression": "http.request.full_uri in $my_redirect_list_1",

            "description": "Bulk Redirect rule 1",

            "action": "redirect",

            "action_parameters": {

                "from_list": {

                    "name": "my_redirect_list_1",

                    "key": "http.request.full_uri"

                }

            }

        },

        {

            "ref": "eval_redirects_list_2",

            "expression": "http.request.full_uri in $my_redirect_list_2",

            "description": "Bulk Redirect rule 2",

            "action": "redirect",

            "action_parameters": {

                "from_list": {

                    "name": "my_redirect_list_2",

                    "key": "http.request.full_uri"

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "67013aa153df4e5fbda92f92bc979331",

    "name": "default",

    "description": "",

    "kind": "root",

    "version": "2",

    "rules": [

      {

        "ref": "eval_redirects_list_1",

        "id": "8be62ab2ef9a4a41af30c24ff8e73e41",

        "version": "1",

        "action": "redirect",

        "action_parameters": {

          "from_list": {

            "name": "my_redirect_list_1",

            "key": "http.request.full_uri"

          }

        },

        "expression": "http.request.full_uri in $my_redirect_list_1",

        "description": "Bulk Redirect rule 1",

        "last_updated": "2021-12-03T15:38:51.658387Z",

        "ref": "8be62ab2ef9a4a41af30c24ff8e73e41",

        "enabled": true

      },

      {

        "ref": "eval_redirects_list_2",

        "id": "97e38797fb2b4b22a4919800f1318a5c",

        "version": "1",

        "action": "redirect",

        "action_parameters": {

          "from_list": {

            "name": "my_redirect_list_2",

            "key": "http.request.full_uri"

          }

        },

        "expression": "http.request.full_uri in $my_redirect_list_2",

        "description": "Bulk Redirect rule 2",

        "last_updated": "2021-12-03T15:38:51.658387Z",

        "ref": "97e38797fb2b4b22a4919800f1318a5c",

        "enabled": true

      }

    ],

    "last_updated": "2021-12-03T15:38:51.658387Z",

    "phase": "http_request_redirect"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

---

## Required API token permissions

The API token used in API requests to manage Bulk Redirects objects (lists, list items, and rules) must have at least the following [permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/):

* [ Dashboard ](#tab-panel-6081)
* [ API ](#tab-panel-6082)

* _Account_ \> _Bulk URL Redirects_ \> _Edit_
* _Account_ \> _Account Filter Lists_ \> _Edit_

* Mass URL Redirects Write
* Account Rule Lists Write

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/bulk-redirects/","name":"Bulk Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/bulk-redirects/create-api/","name":"Create Bulk Redirects via API"}}]}
```

---

---
title: Create Bulk Redirects in the dashboard
description: To create Bulk Redirects in the Cloudflare dashboard you must:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/bulk-redirects/create-dashboard.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create Bulk Redirects in the dashboard

To create Bulk Redirects in the Cloudflare dashboard you must:

1. Create a Bulk Redirect List with one or more URL redirects.
2. Create a Bulk Redirect Rule to enable the URL redirects in the list.

You can create Bulk Redirect Lists and Bulk Redirect Rules in the Cloudflare dashboard:

* At the account level, in **Bulk redirects**.
* At the zone level, go to **Rules** \> **Settings** and select the **Bulk Redirects** tab.

However, the lists and rules only exist at the account level and every zone in the same account will show the same items.

Note

Bulk Redirects require that the incoming traffic for the hostname referenced in visitors' requests is [proxied by Cloudflare](https://developers.cloudflare.com/dns/proxy-status/).

## 1\. Create a Bulk Redirect List

1. In the Cloudflare dashboard, go to the **Bulk redirects** page.  
[ Go to **Bulk redirects** ](https://dash.cloudflare.com/?to=/:account/bulk-redirects)
2. Under **Bulk Redirect Lists**, select **Create Bulk Redirect List**.
3. Enter a list name and description, and select **Next**.
4. You can import a CSV file containing several URL redirects or enter URL redirects one at a time in the dashboard.  
Note  
The source URL of each redirect cannot include a query string. For more information, refer to the [supported URL components](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/reference/url-components/).  
Import a CSV file  
   1. Drag and drop a CSV file containing URL redirects or select **browse** and select a CSV file. For more information on the file format, refer to [CSV file format for Bulk Redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/reference/csv-file-format/).  
   2. The dashboard will display the URL redirects that were successfully imported from the file. You can manually adjust the displayed records or add/remove URL redirects before proceeding.  
   3. Select **Next**.  
Add URL redirects manually  
   1. Select **Or, manually add URL redirects**.  
   2. Enter the URL redirects you wish to add to the list. You must enter at least the following three fields: **Source URL**, **Target URL**, and **Status**. To set additional options, expand **Edit parameters**.  
   3. Add more URL redirects, if required.  
   4. Select **Next**.
5. Review and edit the URL redirects you imported or created, and select **Next**.
6. Select **Continue to Redirect Rules** to go to the rule creation page, and follow the instructions in the next section. You must create a Bulk Redirect Rule to enable the URL redirects you defined.

Notes

Cloudflare will apply the following rules when you add items to an existing list (either manually or via CSV file):

* Do not remove any existing list items before updating/adding items.
* Update items that were already in the list.
* Add items that were not present in the list.

## 2\. Create a Bulk Redirect Rule

1. (Optional) If you are not using the Bulk Redirect List creation wizard according to the instructions in the previous section:  
   1. In the Cloudflare dashboard, go to the **Bulk redirects** page.  
   [ Go to **Bulk redirects** ](https://dash.cloudflare.com/?to=/:account/bulk-redirects)  
   2. Select **Create Bulk Redirect Rule**.
2. In **Rule name**, enter a descriptive name for the rule.
3. Select the Bulk Redirect List you previously created.
4. (Optional) If necessary, select **Or use the expression editor** to edit the [rule expression](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/concepts/#expression) or the [rule key](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/concepts/#key).
5. To save and deploy the Bulk Redirect Rule, select **Save and Deploy**. If you are not ready to deploy your rule, select **Save as Draft**.  
If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to [Troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/#this-rule-may-not-apply-to-your-traffic) for more information.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/bulk-redirects/","name":"Bulk Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/bulk-redirects/create-dashboard/","name":"Create Bulk Redirects in the dashboard"}}]}
```

---

---
title: Bulk Redirects FAQ
description: Below you will find answers to the most commonly asked questions regarding Bulk Redirects.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/bulk-redirects/faq.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Bulk Redirects FAQ

Below you will find answers to the most commonly asked questions regarding Bulk Redirects.

To troubleshoot errors related to Bulk Redirects:

* Refer to [Troubleshooting Cloudflare 10XXX Errors](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-10xxx-errors/) for more information on runtime errors.
* Use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to determine if a rule is triggering for a specific URL.

## What happens if the same source URL appears in two different Bulk Redirect Lists?

In this situation, Cloudflare will use the URL redirect of the first rule that triggers. This will be determined by the order of the Bulk Redirect Rules enabling each Bulk Redirect List in the `http_request_redirect` phase entry point ruleset.

## How can I solve the following error: "This account has reached the limit on the number of URL matching items on the same hostname/path"?

You may get this error when adding items to a Bulk Redirect List.

You can have any number of URL redirects with the same source hostname (with different paths) or same source path (with different hostnames). However, you can have a maximum of 16 source URLs with the same hostname and path across all lists, either enabled by a Bulk Redirect Rule or not.

If you receive this error, check if you have any unused Bulk Redirect Lists with the source hostname and path that caused the error, and remove such items from the list.

## How many URL redirects can I have in a single Bulk Redirect List?

Each account has a maximum number of URL redirects across all lists which depends on your Cloudflare plan. If you wish, you can use all the URL redirects available in your plan in a single Bulk Redirect List, but you will not be able to create any other URL redirects in a different list. Refer to [Availability](https://developers.cloudflare.com/rules/url-forwarding/#availability) for more information.

## How can I redirect based on the non-normalized version of a URL?

Use the `raw.http.request.full_uri` field both in the rule expression and in the key, instead of the default field `http.request.full_uri`. This will take the raw version of the URL into account, that is, the URL received on the Cloudflare global network before applying normalization. Refer to [Bulk Redirects concepts](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/concepts/#bulk-redirect-rules) for more information on using a custom rule expression and a custom key.

## Do Bulk Redirects take precedence over Page Rules?

Yes. Bulk Redirects take precedence over Page Rules redirects. For more information on the execution order of Rules products, refer to [Execution order](https://developers.cloudflare.com/rules/url-forwarding/#execution-order).

## Can I purge an entire Bulk Redirect List in one API call?

If your [Bulk Redirect List](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/concepts/#bulk-redirect-lists) contains 500,001 or more items, you will not be able to purge the entire list in a single API call. Instead, you must make multiple calls to [Delete List Items](https://developers.cloudflare.com/api/resources/rules/subresources/lists/subresources/items/methods/delete/) API end-point, deleting a maximum of 100,000 items per request.

For example, to delete a list with 1,000,000 items, you would need to issue at least 10 API requests.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/bulk-redirects/","name":"Bulk Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/bulk-redirects/faq/","name":"Bulk Redirects FAQ"}}]}
```

---

---
title: How Bulk Redirects work
description: For each incoming request, Cloudflare evaluates all URL redirects of each Bulk Redirect List that is enabled by a Bulk Redirect Rule.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/bulk-redirects/how-it-works.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# How Bulk Redirects work

For each incoming request, Cloudflare evaluates all URL redirects of each Bulk Redirect List that is enabled by a Bulk Redirect Rule.

If there is a match for a URL redirect according to the URL matching algorithm, the redirect action is performed immediately, according to the URL redirect configuration parameters. Cloudflare performs no further processing once a redirect action has been executed.

## Matching the source URL of redirects

The following URL redirect parameters control the matching behavior between the request URL and source URLs of the configured (and enabled) URL redirects:

* **Subpath matching** (default: false)  
   * If `true`, the URL redirect will apply to all paths under the given source path. For example, consider the following source and target URLs of a URL redirect:  
         * Source URL: `https://example.com/foo/`  
         * Target URL: `https://example.com/qux/`  
   * With this configuration and **Subpath matching** enabled, an incoming request to `example.com/foo/bar` will be redirected to `https://example.com/qux/bar`.  
Note  
URL redirects with **Subpath matching** enabled cannot contain more than 16 `/` (slash) characters in the source URL path.
* **Include subdomains** (default: false)  
   * If `true`, the source URL hostname of the URL redirect will also apply to all its subdomains. For example, consider the following source and target URLs of a URL redirect:  
         * Source URL: `https://example.com/about`  
         * Target URL: `https://example.com/newpage`  
   * With this configuration and **Includes subdomains** enabled, incoming requests to `http://a.example.com/about` and `http://a.b.example.com/about` would also match, in addition to the specified domain with no subdomain (`https://example.com/about`).

For detailed information on these parameters, refer to [URL redirect parameters](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/reference/parameters/).

## Configuring the path and query string behavior

The following parameters configure how Cloudflare determines the path and query string of the final target URL:

* **Preserve query string** (default: false)  
   * If `true`, the final target URL will keep the query string of the original request. For example, consider the following source and target URLs of a URL redirect:  
         * Source URL: `https://example.com/about`  
         * Target URL: `https://example.com/newpage`  
   * With this configuration and **Preserve query string** enabled, an incoming request to `http://example.com/about?q=term` would be redirected to `https://example.com/newpage?q=term`. If **Preserve query string** is disabled, the same incoming request would be redirected to `https://example.com/newpage`.
* **Preserve path suffix** (default: true)  
   * Defines if the final target URL will include the parts of the request path that did not match the URL redirect's source URL.  
   * When **Subpath matching** is enabled, the path that was not matched is copied over to the final target URL. For example, consider the following source and target URLs of a URL redirect:  
         * Source URL: `https://example.com/a/`  
         * Target URL: `https://example.com/b/`  
   * An incoming request to `https://example.com/a/foo` will be redirected to `https://example.com/b/foo`.  
   * If you set **Preserve path suffix** to `false`, the same request will still match the redirect, but it will be redirected to `https://example.com/b/`.

For detailed information on these parameters, refer to [URL redirect parameters](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/reference/parameters/).

## URL matching algorithm

The URL of an incoming request matches a URL redirect in a list if:

1. The scheme (`http` or `https`) is the same as the source URL of the URL redirect definition. Source URLs with no scheme will match both `http` and `https`.
2. The hostname is the same as the hostname in the source URL of the URL redirect definition. If **Include subdomains** is enabled, the subdomains of the hostname in the redirect definition will also match.
3. The path is the same as the source URL. If **Subpath matching** is enabled, Cloudflare also considers the subpaths of the path in the URL redirect's source URL when determining if there is a match. For example, a URL redirect with its source URL defined as `example.com/blog` will also match requests to `example.com/blog/foo` and `example.com/blog/bar`.

### Determining the URL redirect to apply

If multiple URL redirects can apply, then the redirect that wins is determined by the following rules:

1. Given two URL redirects with **Subpath matching** enabled, the URL redirect with the most specific path wins over the other URL redirect.  
If there are two URL redirects with source URL paths `/folder` and `/folder/subfolder`, an incoming request for the `/folder/subfolder/item` URL path will match the second redirect (`/folder/subfolder`) because it is more specific.
2. URL redirects with the exact hostname win over URL redirects with the **Include subdomains** option enabled.
3. Given two URL redirects with **Include subdomains** enabled, the URL with the most specific domain wins over the other URL redirect.  
If there are two URL redirects with source URL hostnames `bar.com` and `foo.bar.com`, an incoming request to `qux.foo.bar.com` will match the second redirect (`foo.bar.com`) because it is more specific.
4. URL redirects with a concrete scheme win over URL redirects that match both `http` and `https` schemes.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/bulk-redirects/","name":"Bulk Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/bulk-redirects/how-it-works/","name":"How Bulk Redirects work"}}]}
```

---

---
title: CSV file format for Bulk Redirects
description: You can use a CSV file to import URL redirects into a Bulk Redirect List using the Cloudflare dashboard. Each line in the CSV file must follow this format:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/bulk-redirects/reference/csv-file-format.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# CSV file format for Bulk Redirects

You can use a CSV file to import URL redirects into a Bulk Redirect List [using the Cloudflare dashboard](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/create-dashboard/#1-create-a-bulk-redirect-list). Each line in the CSV file must follow this format:

```

<SOURCE_URL>,<TARGET_URL>[,<STATUS_CODE>,<PRESERVE_QUERY_STRING>,<INCLUDE_SUBDOMAINS>,<SUBPATH_MATCHING>,<PRESERVE_PATH_SUFFIX>]


```

Only the `<SOURCE_URL>` and `<TARGET_URL>` values are mandatory. The default value of `<STATUS_CODE>` is `301` and the default value for all the boolean parameters is `FALSE`.

To enable one of the URL redirect parameters, use one of the following values: `TRUE` or `true`. To keep an option disabled, use one of `FALSE` or `false`, or enter a comma (delimiter) without entering any value.

## Example CSV file

All the lines in this example are valid lines that you can import in the dashboard:

```

example.com/contacts,https://example.net/contact-us,301,,,,

example.com/about,https://example.net/about-us,,FALSE,TRUE,,

example.com/docs,https://example.com/draft-docs,302,,TRUE


```

## Important remarks

* The CSV file must not include a header row with column names.
* A source/target URL must be enclosed in quotes (`"`) when it includes a comma (`,`). You can always enclose URL values in quotes, but it is not required.
* You can skip an optional value by immediately entering a comma (the delimiter) without entering any value.
* You do not need to include trailing commas.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/bulk-redirects/","name":"Bulk Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/bulk-redirects/reference/","name":"Reference"}},{"@type":"ListItem","position":6,"item":{"@id":"/rules/url-forwarding/bulk-redirects/reference/csv-file-format/","name":"CSV file format for Bulk Redirects"}}]}
```

---

---
title: Available fields and functions
description: The available fields when defining a Bulk Redirect Rule filter expression are the following:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/bulk-redirects/reference/fields-functions.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Available fields and functions

The available fields when defining a Bulk Redirect Rule filter expression are the following:

* `cf.edge.server_ip`
* `cf.edge.server_port`
* `cf.edge.client_port`
* `cf.zone.name`
* `cf.metal.id`
* `cf.ray_id`
* `cf.tls_client_auth.*`
* `http.cookie`
* `http.host`
* `http.referer`
* `http.request.headers`
* `http.request.headers.*`
* `http.request.accepted_languages`
* `http.request.method`
* `http.request.timestamp.sec`
* `http.request.timestamp.msec`
* `http.request.full_uri`
* `http.request.uri`
* `http.request.uri.*`
* `http.request.version`
* `raw.http.request.full_uri`
* `raw.http.request.uri`
* `raw.http.request.uri.*`
* `http.user_agent`
* `http.x_forwarded_for`
* `ip.src`
* `ip.src.lat`
* `ip.src.lon`
* `ip.src.asnum`
* `ip.src.city`
* `ip.src.country`
* `ip.src.continent`
* `ip.src.is_in_european_union`
* `ip.src.subdivision_1_iso_code`
* `ip.src.subdivision_2_iso_code`
* `ssl`

Refer to [Fields](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/) for reference information on these fields.

Important

* To obtain the value of an HTTP request header using the [http.request.headers](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.request.headers/) field, specify the header name in **lowercase**. For example, to get the first value of the `Accept-Encoding` request header in an expression, use: `http.request.headers["accept-encoding"][0]`.
* Use the `to_string()` function to get the string representation of a non-string value like an Integer value.

For information on the available functions, refer to [Functions](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/bulk-redirects/","name":"Bulk Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/bulk-redirects/reference/","name":"Reference"}},{"@type":"ListItem","position":6,"item":{"@id":"/rules/url-forwarding/bulk-redirects/reference/fields-functions/","name":"Available fields and functions"}}]}
```

---

---
title: Bulk Redirects API JSON objects
description: A fully populated Bulk Redirect Rule object has the following JSON structure:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/bulk-redirects/reference/json-objects.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Bulk Redirects API JSON objects

## Bulk Redirect Rule

A fully populated Bulk Redirect Rule object has the following JSON structure:

```

{

  "action": "redirect",

  "expression": "http.request.full_uri in $<LIST_NAME>",

  "action_parameters": {

    "from_list": {

      "name": "<LIST_NAME>",

      "key": "http.request.full_uri"

    }

  }

}


```

The JSON object properties must comply with the following:

* `action` must be `redirect`
* `action_parameters` must contain a `from_list` object with additional settings.
* `from_list` must contain the following properties:  
   * `name`: The name of an existing Bulk Redirect List to associate with the current Bulk Redirect Rule.  
   * `key`: An expression that defines the value that will be matched against the configured URL redirect's source URL values, following the rules of the [URL matching algorithm](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/how-it-works/#url-matching-algorithm). Refer to [Bulk Redirects concepts](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/concepts/#bulk-redirect-rules) for more information.
* `expression` must reference the request field used in the `key` property. Refer to [Bulk Redirects concepts](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/concepts/#bulk-redirect-rules) for more information.

## URL redirect list item

A fully populated URL redirect list item object has the following JSON structure:

```

{

  "id": "7c5dae5552338874e5053f2534d2767a",

  "redirect": {

    "source_url": "https://example.com/blog",

    "target_url": "https://example.com/blog/latest",

    "status_code": 301,

    "include_subdomains": false,

    "subpath_matching": false,

    "preserve_query_string": false,

    "preserve_path_suffix": true

  },

  "created_on": "2021-10-11T12:39:02Z",

  "modified_on": "2021-10-11T12:39:02Z"

}


```

For details on the `redirect` object properties, refer to [URL redirect parameters](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/reference/parameters/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/bulk-redirects/","name":"Bulk Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/bulk-redirects/reference/","name":"Reference"}},{"@type":"ListItem","position":6,"item":{"@id":"/rules/url-forwarding/bulk-redirects/reference/json-objects/","name":"Bulk Redirects API JSON objects"}}]}
```

---

---
title: URL redirect parameters
description: A URL redirect has a source URL, a target URL, a status code, and some additional parameters that affect its URL matching behavior and runtime behavior.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/bulk-redirects/reference/parameters.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# URL redirect parameters

A URL redirect has a source URL, a target URL, a status code, and some additional parameters that affect its URL matching behavior and runtime behavior.

## Source URL

API field: `source_url` ` String `

The URL string that the incoming request URL must match for the redirect to be applied. This property is mandatory. The maximum length of the source URL is 32 KB.

The value must be a valid URL, but the URL scheme is not required (for example, `https`); when the scheme is omitted, the redirect applies to both `http` and `https` URL schemes.

A Bulk Redirect List cannot contain several URL redirects with the exact same source URL. The exact behavior of the [URL matching algorithm](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/how-it-works/#url-matching-algorithm), which matches an incoming request with the redirect's source URL, depends on the values of the [**Include subdomains**](#include-subdomains) and [**Subpath matching**](#subpath-matching) parameters.

For more information on the supported URL components, refer to [Supported URL components in Bulk Redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/reference/url-components/).

## Target URL

API field: `target_url` ` String `

The URL where the client will be redirected to when there is a match for the URL redirect. This property is mandatory. The maximum length of the target URL is 32 KB.

The value must be a valid URL. The final target URL depends on the values of the [**Preserve query string**](#preserve-query-string) and [**Preserve path suffix**](#preserve-path-suffix) parameters.

For more information on the supported URL components, refer to [Supported URL components in Bulk Redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/reference/url-components/).

## Subpath matching

API field: `subpath_matching` ` Boolean ` default: false

If `true`, the current redirect will apply the subpath matching algorithm to the request URL when determining if there is a match for the current URL redirect.

For example, a URL redirect from `/my-folder/` to `/other-folder/` with **Subpath matching** enabled will also redirect a request from `/my-folder/item` to `/other-folder/item`. However, the redirect will only include the `item` part when [**Preserve path suffix**](#preserve-path-suffix) is `true`.

For more information, refer to [Matching the source URL of redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/how-it-works/#matching-the-source-url-of-redirects).

## Include subdomains

API field: `include_subdomains` ` Boolean ` default: false

If `true`, the source URL hostname will also apply to any subdomains — the redirect will match for all subdomains to the left of the domain portion of the source URL, as well as the specified domain.

For example, a redirect with source URL defined as `http://example.com/about` will also apply to requests with source URL `http://a.example.com/about` or `http://a.b.example.com/about`.

For more information, refer to [Matching the source URL of redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/how-it-works/#matching-the-source-url-of-redirects).

## Preserve query string

API field: `preserve_query_string` ` Boolean ` default: false

If `true`, the redirect URL will keep the query string of the original request.

For example, a URL redirect from `/my-folder/` to `/other-folder/` with **Preserve query string** enabled will redirect a request from `/my-folder/?name=value` to `/other-folder/?name=value`. If **Preserve query string** is disabled, the request will be redirected from `/my-folder/?name=value` to `/other-folder/`.

## Preserve path suffix

API field: `preserve_path_suffix` ` Boolean ` default: true

Applicable only when [**Subpath matching**](#subpath-matching) is enabled. If `true`, defines that the redirect URL will include the remaining (non-matched) path elements of the source URL, if any.

For example, when both **Subpath matching** and **Preserve path suffix** are enabled, a URL redirect from `/my-folder/` to `/another-folder/` will redirect an incoming request from `/my-folder/foo` to `/another-folder/foo`. If **Preserve path suffix** is disabled, the same request would still match the URL redirect, but it would redirect from `/my-folder/foo` to `/another-folder/`.

## Status code

API field: `status_code` ` Integer ` default: 301

The HTTP status code returned to the client when redirecting.

The value must be one of the following:

* `301` (Moved permanently)
* `302` (Found, also known as Moved temporarily)
* `307` (Temporary redirect)
* `308` (Permanent redirect)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/bulk-redirects/","name":"Bulk Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/bulk-redirects/reference/","name":"Reference"}},{"@type":"ListItem","position":6,"item":{"@id":"/rules/url-forwarding/bulk-redirects/reference/parameters/","name":"URL redirect parameters"}}]}
```

---

---
title: Supported URL components in Bulk Redirects
description: The source and target URLs of a URL redirect support different URL components.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Copy page

# Supported URL components in Bulk Redirects

The source and target URLs of a URL redirect support different URL components.

The provided URL component examples in the reference table are based on the following URL:

```

https://user:password@www.example.com:443/search?q=term#results


```

| URL component                                 | Supported in source URL [1](#user-content-fn-1) | Supported in target URL                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| --------------------------------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Scheme**For example:https                   | Yes, http or https only(optional)               | Yes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| **User information**For example:user:password | No                                              | Yes (optional)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| **Host**For example:www.example.com           | Yes                                             | Yes (optional)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| **Port**For example:443                       | No                                              | Yes (optional)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| **Path**For example:/search                   | Yes                                             | Yes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| **Query string**For example:q=term            | No                                              | Yes, if [**Preserve query string**](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/reference/parameters/#preserve-query-string) is false (optional)You can only add a query string to the target URL if you do not keep the original query string (that is, if **Preserve query string** is false). If you set **Preserve query string** to true, the query string of the request will be passed along [when there is a match for the source URL](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/how-it-works/#matching-the-source-url-of-redirects). |
| **Fragment**For example:results               | No                                              | Yes (optional)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |

Bulk Redirects also support target URLs without an authority component [2](#user-content-fn-2), like the following URL:

```

magnet:?xt=urn:btih:2bd9d334e8d1e5bd7768755173222db5c6dea13b&dn=archlinux-2021.07.01-x86_64.iso


```

## Footnotes

1. **Supported in source URL** \= **No** means that you cannot include the component in the source URL to match against the URL of incoming requests. [↩](#user-content-fnref-1)
2. The URL authority is the combination of user information, host, and port components. [↩](#user-content-fnref-2)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/bulk-redirects/","name":"Bulk Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/bulk-redirects/reference/","name":"Reference"}},{"@type":"ListItem","position":6,"item":{"@id":"/rules/url-forwarding/bulk-redirects/reference/url-components/","name":"Supported URL components in Bulk Redirects"}}]}
```

---

---
title: Configure Bulk Redirects using Terraform
description: This Terraform example configures account-level Bulk Redirects. It creates a Bulk Redirect List populated with URL redirects and a corresponding Bulk Redirect Rule to activate them.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/bulk-redirects/terraform-example.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Configure Bulk Redirects using Terraform

Note

Terraform code snippets below refer to the v4 SDK only.

This Terraform example configures account-level Bulk Redirects. It creates a [Bulk Redirect List](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/concepts/#bulk-redirect-lists) populated with [URL redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/concepts/#url-redirects) and a corresponding [Bulk Redirect Rule](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/concepts/#bulk-redirect-rules) to activate them.

```

# Cloudflare account ID

variable "cloudflare_account_id" {

  default = "<ACCOUNT_ID>"

}


# Bulk redirect list description

variable "bulk_redirect_list_description" {

  default = "my bulk redirect description"

}


# Bulk redirect list name

variable "bulk_redirect_list_name" {

  default = "my_bulk_redirect_list_name"

}


# Bulk redirect list item (URL redirect)

variable "bulk_redirects" {

  type = map(object({

    source_url  = string

    target_url  = string

    status_code = number

  }))


  default = {

    "redirect1" = {

      source_url = "https://source.url/redirect/1"

      target_url = "https://target.url/?redirect=1"

      status_code = 301

    }

    "redirect2" = {

      source_url = "https://source.url/redirect/2"

      target_url = "https://target.url/?redirect=2"

      status_code = 302

    }

    "redirect3" = {

      source_url = "https://source.url/redirect/3"

      target_url = "https://target.url/?redirect=3"

      status_code = 307

    }

  }

}


# Create redirect list

resource "cloudflare_list" "bulk_redirect_to_id" {

  account_id  = var.cloudflare_account_id

  name        = var.bulk_redirect_list_name

  description = var.bulk_redirect_list_description

  kind        = "redirect"

}


# Add redirect item into the redirect list

resource "cloudflare_list_item" "bulk_redirect_to_id_item" {

  for_each = { for redirect in var.bulk_redirects : "${redirect.source_url}" => redirect }


  account_id = var.cloudflare_account_id

  list_id    = cloudflare_list.bulk_redirect_to_id.id


  redirect {

    source_url  = each.value.source_url

    target_url  = each.value.target_url

    status_code = each.value.status_code

  }


  depends_on = [

    cloudflare_list.bulk_redirect_to_id

  ]


}


# Create bulk redirect and attach redirect list

resource "cloudflare_ruleset" "bulk_root_redirect_to_id" {

  account_id  = var.cloudflare_account_id

  name        = var.bulk_redirect_list_name

  description = var.bulk_redirect_list_description

  kind        = "root"

  phase       = "http_request_redirect"


  rules {

    action = "redirect"

    action_parameters {

      from_list {

        name = var.bulk_redirect_list_name

        key  = "http.request.full_uri"

      }

    }

    expression  = "http.request.full_uri in ${"$"}${var.bulk_redirect_list_name}"

    description = var.bulk_redirect_list_description

    enabled     = true

  }


  depends_on = [

    cloudflare_list_item.bulk_redirect_to_id_item

  ]

}


```

## Required token permissions

Your API token must have at least the following [permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/):

* [ Dashboard ](#tab-panel-6083)
* [ API ](#tab-panel-6084)

* Account Filter Lists > Edit
* Bulk URL Redirects > Edit

* Account Rule Lists Write
* Bulk URL Redirects Write

## Additional resources

For additional guidance on using Terraform with Cloudflare, refer to the following resources:

* [Terraform documentation](https://developers.cloudflare.com/terraform/)
* [Cloudflare Provider for Terraform ↗](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs) (reference documentation)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/bulk-redirects/","name":"Bulk Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/bulk-redirects/terraform-example/","name":"Configure Bulk Redirects using Terraform"}}]}
```

---

---
title: Redirect examples
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/examples/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Redirect examples

[Perform mobile redirectsCreate a redirect rule to redirect visitors using mobile devices to a different hostname.](https://developers.cloudflare.com/rules/url-forwarding/examples/perform-mobile-redirects/)[Redirect admin area requests to HTTPSCreate a redirect rule to redirect requests for the administration area of store.example.com to HTTPS, keeping the original path and query string.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-admin-https/)[Redirect requests from one domain to anotherCreate a redirect rule to redirect all requests to a different domain, maintaining all functionality, except for the discontinued HTTP service (port 80).](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-all-another-domain/)[Redirect requests from one country to a domainCreate a redirect rule to redirect all website visitors from the United Kingdom to a different domain, maintaining the current functionality in the same paths.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-all-country/)[Redirect requests for a domain to a new domainCreate a redirect rule to redirect all URLs for a domain to point to the root of a new domain, including any subdomains of the old domain.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-all-different-domain-root/)[Redirect requests to a different hostnameCreate a redirect rule to redirect all requests for smallshop.example.com to a different hostname using HTTPS, keeping the original path and query string.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-all-different-hostname/)[Redirect local visitors to specific subdomainsCreate a redirect rule to redirect United Kingdom and France visitors from the example.com website's root path (/) to their localized subdomains https://gb.example.com and https://fr.example.com, respectively.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-country-subdomains/)[Redirect visitors to a new page URLCreate a redirect rule to redirect visitors from /contact-us/ to the page's new path /contacts/.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-new-url/)[Redirect from root to WWWCreate a redirect rule to forward HTTPS requests from the root (also known as the “apex” or “naked” domain) to the WWW subdomain.](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-root-to-www/)[Redirect from WWW to rootCreate a redirect rule to forward HTTPS requests from the WWW subdomain to the root (also known as the “apex” or “naked” domain).](https://developers.cloudflare.com/rules/url-forwarding/examples/redirect-www-to-root/)[Remove locale from URL pathCreate a redirect rule to redirect visitors from an old URL format with locale information to a new URL format.](https://developers.cloudflare.com/rules/url-forwarding/examples/remove-locale-url/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/examples/","name":"Redirect examples"}}]}
```

---

---
title: Perform mobile redirects
description: Create a redirect rule to redirect visitors using mobile devices to a different hostname.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/examples/perform-mobile-redirects.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Perform mobile redirects

Create a redirect rule to redirect visitors using mobile devices to a different hostname.

The following examples will redirect visitors using mobile devices — based on the request user agent string — to a different hostname.

## Redirect mobile users dropping the original URI path

This example static redirect will redirect requests for the current zone (`example.com`) from mobile users to `m.example.com` without preserving the URI path in the original HTTP request.

**When incoming requests match**

* Enter the following expression in the [Expression Editor](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/#expression-editor):  
`not http.host in {"m.example.com"} and (http.user_agent contains "mobi" or http.user_agent contains "Mobi")`

**Then**

* **Type:** _Static_
* **URL:** `m.example.com`
* **Status code:** _301_

Notes about this example:

* The `not http.host in {"m.example.com"}` condition prevents redirect loops.
* The user agent condition follows [Mozilla's recommendation ↗](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/User-Agent/Firefox#device-specific%5Fuser%5Fagent%5Fstrings) for identifying mobile devices.
* The **Then** \> **URL** value should be the same as the one you entered in the `http.host` condition of the rule's filter expression.
* You can redirect users to other zones on Cloudflare or to other hostnames not on Cloudflare.

## Redirect mobile users keeping the original path

This example single redirect will redirect requests for the current zone (`example.com`) from mobile users to `m.example.com`, keeping the URI path of the original HTTP request.

**When incoming requests match**

* Enter the following expression in the [Expression Editor](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/#expression-editor):  
`not http.host in {"m.example.com"} and (http.user_agent contains "mobi" or http.user_agent contains "Mobi")`

**Then**

* **Type:** _Dynamic_
* **Expression:** `concat("https://m.example.com", http.request.uri.path)`
* **Status code:** _301_

Notes about this example:

* The `not http.host in {"m.example.com"}` condition prevents redirect loops.
* The user agent condition follows [Mozilla's recommendation ↗](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/User-Agent/Firefox#device-specific%5Fuser%5Fagent%5Fstrings) for identifying mobile devices.
* The hostname in **Then** \> **Expression** should be the same as the one you entered in the `http.host` condition of the rule's filter expression.
* Depending on your use case, you may want to enable **Then** \> **Preserve query string** to also keep the query string of the original request.
* You can redirect users to other zones on Cloudflare or to other hostnames not on Cloudflare.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/examples/","name":"Redirect examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/examples/perform-mobile-redirects/","name":"Perform mobile redirects"}}]}
```

---

---
title: Redirect admin area requests to HTTPS
description: Create a redirect rule to redirect requests for the administration area of `store.example.com` to HTTPS, keeping the original path and query string.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/examples/redirect-admin-https.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Redirect admin area requests to HTTPS

Create a redirect rule to redirect requests for the administration area of `store.example.com` to HTTPS, keeping the original path and query string.

This example single redirect for zone `example.com` will redirect requests for the administration area of a specific subdomain (`store.example.com`) to HTTPS, keeping the original path and query string.

**When incoming requests match**

* **Wildcard pattern**  
   * **Request URL**: `http://store.example.com/admin*`

**Then**

* **Target URL**: `https://store.example.com/admin${1}`
* **Status code:** _301_
* **Preserve query string:** Enabled

For example, the redirect rule would perform the following redirects:

| Request URL                                      | Target URL                                        | Status code |
| ------------------------------------------------ | ------------------------------------------------- | ----------- |
| http://store.example.com/admin/products/         | https://store.example.com/admin/products/         | 301         |
| https://store.example.com/admin/products/        | (unchanged)                                       | n/a         |
| http://store.example.com/admin/?logged\_out=true | https://store.example.com/admin/?logged\_out=true | 301         |
| http://store.example.com/?all\_items=true        | (unchanged)                                       | n/a         |
| http://example.com/admin/                        | (unchanged)                                       | n/a         |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/examples/","name":"Redirect examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/examples/redirect-admin-https/","name":"Redirect admin area requests to HTTPS"}}]}
```

---

---
title: Redirect requests from one domain to another
description: Create a redirect rule to redirect all requests to a different domain, maintaining all functionality, except for the discontinued HTTP service (port 80).
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/examples/redirect-all-another-domain.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Redirect requests from one domain to another

Create a redirect rule to redirect all requests to a different domain, maintaining all functionality, except for the discontinued HTTP service (port 80).

In this example the original domain was replaced with a different domain. All functionality was maintained, except for the HTTP service (port 80) which was discontinued.

[Create a redirect rule](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/create-dashboard/) with the following configuration:

**When incoming requests match**

* **Wildcard pattern**  
   * **Request URL**: `http*://example.com/*`

**Then**

* **Target URL**: `https://example.net/${2}`
* **Status code:** _301_
* **Preserve query string:** Enabled

This configuration will perform the following redirects:

| Request URL                             | URL after redirect                      | Status code |
| --------------------------------------- | --------------------------------------- | ----------- |
| http://example.com/                     | https://example.net/                    | 301         |
| https://example.com/                    | https://example.net/                    | 301         |
| https://example.com/my/path/to/page.htm | https://example.net/my/path/to/page.htm | 301         |
| https://example.com/search?q=term       | https://example.net/search?q=term       | 301         |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/examples/","name":"Redirect examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/examples/redirect-all-another-domain/","name":"Redirect requests from one domain to another"}}]}
```

---

---
title: Redirect requests from one country to a domain
description: Create a redirect rule to redirect all website visitors from the United Kingdom to a different domain, maintaining the current functionality in the same paths.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/examples/redirect-all-country.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Redirect requests from one country to a domain

Create a redirect rule to redirect all website visitors from the United Kingdom to a different domain, maintaining the current functionality in the same paths.

In this example, all website visitors from the United Kingdom will be redirected to a different domain, but maintaining current functionality in the same paths.

1. Create a Bulk Redirect List named `uk_redirect_list` with the following URL redirect:  
   * **Source URL**: `https://example.com/`  
   * **Target URL**: `https://example.co.uk/`  
   * **Subpath matching**: Enabled  
   * **Preserve query string**: Enabled
2. Create a Bulk Redirect Rule that enables the previous Bulk Redirect List and set the rule expression to the following:  
```  
ip.src.country == "GB" and http.request.full_uri in $uk_redirect_list  
```

This configuration will perform the following redirects for UK visitors:

| Request URL                             | URL after redirect                        |
| --------------------------------------- | ----------------------------------------- |
| https://example.com/                    | https://example.co.uk/                    |
| https://example.com/my/path/to/page.htm | https://example.co.uk/my/path/to/page.htm |
| https://example.com/search?q=term       | https://example.co.uk/search?q=term       |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/examples/","name":"Redirect examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/examples/redirect-all-country/","name":"Redirect requests from one country to a domain"}}]}
```

---

---
title: Redirect requests for a domain to a new domain
description: Create a redirect rule to redirect all URLs for a domain to point to the root of a new domain, including any subdomains of the old domain.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/examples/redirect-all-different-domain-root.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Redirect requests for a domain to a new domain

Create a redirect rule to redirect all URLs for a domain to point to the root of a new domain, including any subdomains of the old domain.

In this example, an old website was discontinued and replaced by a new one in a different domain. The functionality is different, and all URLs should now point to the root of the new domain. The same applies to any subdomains of the old domain.

[Create a redirect rule](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/create-dashboard/) with the following configuration:

**When incoming requests match**

* **Wildcard pattern**  
   * **Request URL**: `http*://*example.com/*`

**Then**

* **Target URL**: `https://example.net/`
* **Status code:** _301_

For example, the redirect rule would perform the following redirects:

| Request URL                             | Target URL           | Status code |
| --------------------------------------- | -------------------- | ----------- |
| http://example.com/                     | https://example.net/ | 301         |
| https://example.com/                    | https://example.net/ | 301         |
| https://subdomain.example.com/          | https://example.net/ | 301         |
| https://example.com/my/path/to/page.htm | https://example.net/ | 301         |
| https://example.com/search?q=term       | https://example.net/ | 301         |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/examples/","name":"Redirect examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/examples/redirect-all-different-domain-root/","name":"Redirect requests for a domain to a new domain"}}]}
```

---

---
title: Redirect requests to a different hostname
description: Create a redirect rule to redirect all requests for `smallshop.example.com` to a different hostname using HTTPS, keeping the original path and query string.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/examples/redirect-all-different-hostname.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Redirect requests to a different hostname

Create a redirect rule to redirect all requests for `smallshop.example.com` to a different hostname using HTTPS, keeping the original path and query string.

This example single redirect will redirect all requests for `smallshop.example.com` to a different hostname `globalstore.example.net` using HTTPS, keeping the original path and query string.

**When incoming requests match**

* **Wildcard pattern**  
   * **Request URL**: `http*://smallshop.example.com/*`

**Then**

* **Target URL**: `https://globalstore.example.net/${2}`
* **Status code:** _301_
* **Preserve query string:** Enabled

For example, the redirect rule would perform the following redirects:

| Request URL                                          | Target URL                                              | Status code |
| ---------------------------------------------------- | ------------------------------------------------------- | ----------- |
| http://smallshop.example.com/                        | https://globalstore.example.net/                        | 301         |
| http://smallshop.example.com/admin/?logged\_out=true | https://globalstore.example.net/admin/?logged\_out=true | 301         |
| https://smallshop.example.com/?all\_items=1          | https://globalstore.example.net/?all\_items=1           | 301         |
| http://example.com/about/                            | (unchanged)                                             | n/a         |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/examples/","name":"Redirect examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/examples/redirect-all-different-hostname/","name":"Redirect requests to a different hostname"}}]}
```

---

---
title: Redirect local visitors to specific subdomains
description: Create a redirect rule to redirect United Kingdom and France visitors from the `example.com` website's  root path (`/`) to their localized subdomains `https://gb.example.com` and `https://fr.example.com`, respectively.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/examples/redirect-country-subdomains.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Redirect local visitors to specific subdomains

Create a redirect rule to redirect United Kingdom and France visitors from the `example.com` website's root path (`/`) to their localized subdomains `https://gb.example.com` and `https://fr.example.com`, respectively.

This example single redirect for zone `example.com` will redirect United Kingdom and France visitors requesting the website's root path (`/`) to their localized subdomains `https://gb.example.com` and `https://fr.example.com`, respectively.

**When incoming requests match**

Using the Expression Editor:  
`(ip.src.country eq "GB" or ip.src.country eq "FR") and http.request.uri.path eq "/"`

**Then**

* **Type:** _Dynamic_
* **Expression:** `lower(concat("https://", ip.src.country, ".example.com"))`
* **Status code:** _301_

For example, the redirect rule would perform the following redirects:

| Visitor country | Request URL | Target URL             | Status code |
| --------------- | ----------- | ---------------------- | ----------- |
| United Kingdom  | example.com | https://gb.example.com | 301         |
| France          | example.com | https://fr.example.com | 301         |
| United States   | example.com | (unchanged)            | n/a         |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/examples/","name":"Redirect examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/examples/redirect-country-subdomains/","name":"Redirect local visitors to specific subdomains"}}]}
```

---

---
title: Redirect visitors to a new page URL
description: Create a redirect rule to redirect visitors from `/contact-us/` to the page's new path `/contacts/`.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/examples/redirect-new-url.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Redirect visitors to a new page URL

Create a redirect rule to redirect visitors from `/contact-us/` to the page's new path `/contacts/`.

This example static redirect for zone `example.com` will redirect visitors requesting the `/contact-us/` page to the new page URL `/contacts/`.

**When incoming requests match**

* **Field:** _URI Path_
* **Operator:** _equals_
* **Value:** `/contact-us/`

If you are using the Expression Editor, enter the following expression:  
`http.request.uri.path eq "/contact-us/"`

**Then**

* **Type:** _Static_
* **URL:** `/contacts/`
* **Status code:** _301_
* **Preserve query string:** Enabled

For example, the redirect rule would perform the following redirects:

| Request URL                      | Target URL                     | Status code |
| -------------------------------- | ------------------------------ | ----------- |
| example.com/contact-us/          | example.com/contacts/          | 301         |
| example.com/contact-us/?state=TX | example.com/contacts/?state=TX | 301         |
| example.com/team/                | (unchanged)                    | n/a         |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/examples/","name":"Redirect examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/examples/redirect-new-url/","name":"Redirect visitors to a new page URL"}}]}
```

---

---
title: Redirect from root to WWW
description: Create a redirect rule to forward HTTPS requests from the root (also known as the “apex” or “naked” domain) to the WWW subdomain.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/examples/redirect-root-to-www.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Redirect from root to WWW

Create a redirect rule to forward HTTPS requests from the root (also known as the “apex” or “naked” domain) to the WWW subdomain.

This example creates a redirect rule that forwards HTTPS requests from the root domain (`example.com`) to the WWW subdomain (`www.example.com`), while retaining the original path and query string.

**When incoming requests match**

* **Wildcard pattern**  
   * **Request URL**: `https://example.com/*`

**Then**

* **Target URL**: `https://www.example.com/${1}`
* **Status code**: _301_
* **Preserve query string**: Enabled

This rule ensures that only HTTPS requests from the root domain are redirected to the WWW subdomain, leaving other requests (such as HTTP or requests to other subdomains) unchanged.

For example, the redirect rule would perform the following redirects:

| Request URL                                 | Target URL                                      | Status code |
| ------------------------------------------- | ----------------------------------------------- | ----------- |
| https://example.com/products/               | https://www.example.com/products/               | 301         |
| https://store.example.com/products/         | (unchanged)                                     | n/a         |
| https://example.com/admin/?logged\_out=true | https://www.example.com/admin/?logged\_out=true | 301         |
| http://example.com/?all\_items=true         | (unchanged)                                     | n/a         |
| http://www.example.com/admin/               | (unchanged)                                     | n/a         |

Make sure to replace `example.com` with your actual hostname before deploying your rule.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/examples/","name":"Redirect examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/examples/redirect-root-to-www/","name":"Redirect from root to WWW"}}]}
```

---

---
title: Redirect from WWW to root
description: Create a redirect rule to forward HTTPS requests from the WWW subdomain to the root (also known as the “apex” or “naked” domain).
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/examples/redirect-www-to-root.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Redirect from WWW to root

Create a redirect rule to forward HTTPS requests from the WWW subdomain to the root (also known as the “apex” or “naked” domain).

This example creates a redirect rule that forwards HTTPS requests from the WWW subdomain (`www.example.com`) to the root domain (`example.com`), while retaining the original path and query string.

**When incoming requests match**

* **Wildcard pattern**  
   * **Request URL**: `https://www.*`

**Then**

* **Target URL**: `https://${1}`
* **Status code**: _301_
* **Preserve query string**: Enabled

This rule ensures that only HTTPS requests from `www.` subdomains are redirected to the root domain, leaving other requests (such as HTTP or non-WWW) unchanged.

For example, the redirect rule would perform the following redirects:

| Request URL                                     | Target URL                                  | Status code |
| ----------------------------------------------- | ------------------------------------------- | ----------- |
| https://www.example.com/products/               | https://example.com/products/               | 301         |
| https://www.store.example.com/products/         | https://store.example.com/products/         | 301         |
| https://store.example.com/products/             | (unchanged)                                 | n/a         |
| https://www.example.com/admin/?logged\_out=true | https://example.com/admin/?logged\_out=true | 301         |
| http://www.example.com/?all\_items=true         | (unchanged)                                 | n/a         |
| http://example.com/admin/                       | (unchanged)                                 | n/a         |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/examples/","name":"Redirect examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/examples/redirect-www-to-root/","name":"Redirect from WWW to root"}}]}
```

---

---
title: Remove locale from URL path
description: Create a redirect rule to redirect visitors from an old URL format with locale information to a new URL format.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/examples/remove-locale-url.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Remove locale from URL path

Create a redirect rule to redirect visitors from an old URL format with locale information to a new URL format.

This example single redirect for zone `example.com` will redirect visitors from an old URL format that included the locale (for example, `/en-us/<page_name>`) to the new format `/<page_name>`.

**When incoming requests match**

* **Field:** _URI Path_
* **Operator:** _matches regex_
* **Value:** `^/[A-Za-z]{2}-[A-Za-z]{2}/`

If you are using the Expression Editor, enter the following expression:  
`http.request.uri.path matches "^/[A-Za-z]{2}-[A-Za-z]{2}/"`

**Then**

* **Type:** _Dynamic_
* **Expression:** `regex_replace(http.request.uri.path, "^/[A-Za-z]{2}-[A-Za-z]{2}/(.*)", "/${1}")`
* **Status code:** _301_
* **Preserve query string:** Enabled

The function [regex\_replace()](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#regex%5Freplace) allows you to extract parts of the URL using regular expressions' capture groups. Create capture groups by putting part of the regular expression in parentheses. Then, reference a capture group using `${<num>}` in the replacement string, where `<num>` is the number of the capture group.

For example, the redirect rule would perform the following redirects:

| Request URL                           | Target URL                      | Status code |
| ------------------------------------- | ------------------------------- | ----------- |
| example.com/en-us/meet-our-team       | example.com/meet-our-team       | 301         |
| example.com/pt-BR/meet-our-team       | example.com/meet-our-team       | 301         |
| example.com/en-us/calendar?view=month | example.com/calendar?view=month | 301         |
| example.com/meet-our-team             | (unchanged)                     | n/a         |
| example.com/robots.txt                | (unchanged)                     | n/a         |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/examples/","name":"Redirect examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/examples/remove-locale-url/","name":"Remove locale from URL path"}}]}
```

---

---
title: Single Redirects
description: Single Redirects allow you to create static or dynamic URL redirects. A simple interface with wildcard support makes it easy to define source and target URL patterns without needing complex functions or regular expressions, efficiently handling thousands of URLs with a single rule. Dynamic URL redirects also support advanced features such as string replacement operations and regular expressions (depending on your Cloudflare plan).
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/single-redirects/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Single Redirects

Single Redirects allow you to create static or dynamic URL redirects. A simple interface with [wildcard support](https://developers.cloudflare.com/ruleset-engine/rules-language/operators/#wildcard-matching) makes it easy to define source and target URL patterns without needing complex functions or regular expressions, efficiently handling thousands of URLs with a single rule. Dynamic URL redirects also support advanced features such as string replacement operations and [regular expressions](https://developers.cloudflare.com/ruleset-engine/rules-language/values/#string-values-and-regular-expressions) (depending on your Cloudflare plan).

For more complex and customized redirect logic, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

---

## Related resources

* [Availability](https://developers.cloudflare.com/rules/url-forwarding/#availability): Information on the Single Redirects quotas and features per Cloudflare plan.
* [Execution order](https://developers.cloudflare.com/rules/url-forwarding/#execution-order): Execution order of the different Rules products.
* [Trace a request](https://developers.cloudflare.com/rules/trace-request/): Use Cloudflare Trace to determine if a redirect rule is triggering for a specific URL.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/single-redirects/","name":"Single Redirects"}}]}
```

---

---
title: Create a redirect rule via API
description: Use the Rulesets API to create a redirect rule via API.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/single-redirects/create-api.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a redirect rule via API

Use the [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/) to create a redirect rule via API.

Add redirect rules to the entry point ruleset of the `http_request_dynamic_redirect` phase at the zone level. Refer to the [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/) documentation for more information on [creating a ruleset](https://developers.cloudflare.com/ruleset-engine/rulesets-api/create/) and supplying a list of rules for the ruleset.

Note

Single Redirects require that the incoming traffic for the hostname referenced in visitors' requests is [proxied by Cloudflare](https://developers.cloudflare.com/dns/proxy-status/).

## Basic rule settings

A redirect rule must have:

* `action` set to `redirect`
* An `action_parameters` object with additional configuration settings — refer to [Single Redirects settings](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/settings/) for details.

## Example requests

The following request of the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) operation creates a phase entry point ruleset for the `http_request_dynamic_redirect` phase at the zone level, and defines a single redirect rule with a dynamic URL redirect. Use this operation if you have not created a phase entry point ruleset for the `http_request_dynamic_redirect` phase yet.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Create a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets" \

  --request POST \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "name": "Redirect rules ruleset",

    "kind": "zone",

    "phase": "http_request_dynamic_redirect",

    "rules": [

        {

            "ref": "redirect_gb_fr_to_localized",

            "expression": "(ip.src.country eq \"GB\" or ip.src.country eq \"FR\") and http.request.uri.path eq \"/\"",

            "description": "Redirect GB and FR users in home page to localized site.",

            "action": "redirect",

            "action_parameters": {

                "from_value": {

                    "target_url": {

                        "expression": "lower(concat(\"https://\", ip.src.country, \".example.com\"))"

                    },

                    "status_code": 307,

                    "preserve_query_string": true

                }

            }

        }

    ]

  }'


```

Response

```

{

  "result": {

    "id": "528f4f03bf0da53a29907199625867be",

    "name": "Redirect rules ruleset",

    "kind": "zone",

    "version": "1",

    "rules": [

      {

        "ref": "redirect_gb_fr_to_localized",

        "id": "235e557b92fd4e5e8753ee665a9ddd75",

        "version": "1",

        "expression": "(ip.src.country eq \"GB\" or ip.src.country eq \"FR\") and http.request.uri.path eq \"/\"",

        "description": "Redirect GB and FR users in home page to localized site.",

        "action": "redirect",

        "action_parameters": {

          "from_value": {

            "target_url": {

              "expression": "lower(concat(\"https://\", ip.src.country, \".example.com\"))"

            },

            "status_code": 307,

            "preserve_query_string": true

          }

        },

        "last_updated": "2022-09-28T09:20:42Z"

      }

    ],

    "last_updated": "2022-09-28T09:20:42Z",

    "phase": "http_request_dynamic_redirect"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

If there is already a phase entry point ruleset for the `http_request_dynamic_redirect` phase, use the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation instead, like in the following example:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "name": "Redirect rules ruleset",

    "kind": "zone",

    "phase": "http_request_dynamic_redirect",

    "rules": [

        {

            "ref": "redirect_gb_fr_to_localized",

            "expression": "(ip.src.country eq \"GB\" or ip.src.country eq \"FR\") and http.request.uri.path eq \"/\"",

            "description": "Redirect GB and FR users in home page to localized site.",

            "action": "redirect",

            "action_parameters": {

                "from_value": {

                    "target_url": {

                        "expression": "lower(concat(\"https://\", ip.src.country, \".example.com\"))"

                    },

                    "status_code": 307,

                    "preserve_query_string": true

                }

            }

        },

        {

            "ref": "redirect_contacts_to_new_page",

            "expression": "http.request.uri.path eq \"/contacts.html\"",

            "description": "Redirect to new contacts page.",

            "action": "redirect",

            "action_parameters": {

                "from_value": {

                    "target_url": {

                        "value": "https://example.com/contact-us/"

                    },

                    "status_code": 308

                }

            }

        }

    ]

  }'


```

Response

```

{

  "result": {

    "id": "528f4f03bf0da53a29907199625867be",

    "name": "Redirect rules ruleset",

    "description": "",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "ref": "redirect_gb_fr_to_localized",

        "id": "235e557b92fd4e5e8753ee665a9ddd75",

        "version": "1",

        "action": "redirect",

        "action_parameters": {

          "from_value": {

            "target_url": {

              "expression": "lower(concat(\"https://\", ip.src.country, \".example.com\"))"

            },

            "status_code": 307,

            "preserve_query_string": true

          }

        },

        "expression": "(ip.src.country eq \"GB\" or ip.src.country eq \"FR\") and http.request.uri.path eq \"/\"",

        "description": "Redirect GB and FR users in home page to localized site.",

        "last_updated": "2022-10-03T15:38:51.658387Z",

        "ref": "235e557b92fd4e5e8753ee665a9ddd75",

        "enabled": true

      },

      {

        "ref": "redirect_contacts_to_new_page",

        "id": "cfad5efbfcd1440fb5b30cf30f95ece3",

        "version": "1",

        "action": "redirect",

        "action_parameters": {

          "from_value": {

            "target_url": {

              "value": "https://example.com/contact-us/"

            },

            "status_code": 308

          }

        },

        "expression": "http.request.uri.path eq \"/contacts.html\"",

        "description": "Redirect to new contacts page.",

        "last_updated": "2022-10-03T15:38:51.658387Z",

        "ref": "cfad5efbfcd1440fb5b30cf30f95ece3",

        "enabled": true

      }

    ],

    "last_updated": "2022-10-03T15:38:51.658387Z",

    "phase": "http_request_dynamic_redirect"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

---

## Required API token permissions

The API token used in API requests to manage redirect rules must have at least the following permission:

* _Zone_ \> _Single Redirect_ \> _Edit_

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/single-redirects/","name":"Single Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/single-redirects/create-api/","name":"Create a redirect rule via API"}}]}
```

---

---
title: Create a redirect rule in the dashboard
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/single-redirects/create-dashboard.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a redirect rule in the dashboard

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Create rule** \> **Redirect Rule**.
3. (Optional) Select one of the rule templates that address common use cases. Then, review and adjust the proposed rule configuration.
4. Enter a descriptive name for the rule in **Rule name**.
5. Under **When incoming requests match**, select one of the following options:  
   * **Wildcard pattern**: The rule will only apply to traffic matching the wildcard pattern.  
         * **Request URL**: Enter the [wildcard pattern](https://developers.cloudflare.com/ruleset-engine/rules-language/operators/#wildcard-matching) using the asterisk (`*`) character to match multiple requests. For example, `http*://*.example.com/files/*`.  
         * **Then**: Define the [URL redirect settings](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/settings/) including:  
                  * **Target URL**: Enter the target URL, which can be static (for example, `https://example.com`) or dynamic (for example, `https://example.com/${1}/files/${2}`). Use [wildcard replacement](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#wildcard%5Freplace) such as `${1}` and `${2}` to define dynamic target URLs.  
                  * **Status code**: Select the status code for the redirect (for example, `301`).  
                  * **Preserve query string**: Choose whether to keep the query string from the original request.  
   * **All incoming requests**: The rule will apply to all traffic.  
         * **Then**: Define the [URL redirect settings](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/settings/) for all incoming requests.  
   * **Custom filter expression**: The rule will only apply to traffic matching a custom expression. Define the [rule expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/) to configure which requests should be redirected.  
         * **Then**: Define the [URL redirect settings](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/settings/) for requests matching the custom rule expression.
6. To save and deploy your rule, select **Deploy**. If you are not ready to deploy your rule, select **Save as Draft**.  
If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to [Troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/#this-rule-may-not-apply-to-your-traffic) for more information.

Note

Single Redirects require that the incoming traffic for the hostname referenced in visitors' requests is [proxied by Cloudflare](https://developers.cloudflare.com/dns/proxy-status/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/single-redirects/","name":"Single Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/single-redirects/create-dashboard/","name":"Create a redirect rule in the dashboard"}}]}
```

---

---
title: Single Redirects settings
description: The following sections describe the settings of redirect rules to configure static and dynamic URL redirects.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/single-redirects/settings.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Single Redirects settings

The following sections describe the settings of redirect rules to configure static and dynamic URL redirects.

## Wildcard URL Redirect

Performs a URL redirect using [wildcard patterns](https://developers.cloudflare.com/ruleset-engine/rules-language/operators/#wildcard-matching) to match multiple requests. This method simplifies defining source and target URL patterns without needing complex expressions.

A wildcard URL redirect has the following configuration parameters:

* **Request URL**: Enter the [wildcard pattern](https://developers.cloudflare.com/ruleset-engine/rules-language/operators/#wildcard-matching) using the asterisk (`*`) character to match multiple requests. For example, `https://*.example.com/files/*`.
* **Target URL**: Enter the target URL, which can be static (for example, `https://example.com`) or dynamic (for example, `https://example.com/${1}/files/${2}`). Use [wildcard replacement](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#wildcard%5Freplace) like `${1}`, `${2}`, etc., to define dynamic targets.
* **Status code**: The HTTP status code of the redirect response (_301_ by default). Must be one of the following: _301_ (Moved permanently), _302_ (Found, also known as Moved temporarily), _307_ (Temporary redirect), or _308_ (Permanent redirect).
* **Preserve query string**: Whether to preserve the query string when redirecting (disabled by default).

## Static URL redirect

Performs a static URL redirect with a given HTTP status code and optionally preserves the query string.

A static URL redirect has the following configuration parameters:

* **URL**: A literal string that will be used in the `Location` HTTP header returned in the redirect response.
* **Status code**: The HTTP status code of the redirect response (_301_ by default). Must be one of the following: _301_ (Moved permanently), _302_ (Found, also known as Moved temporarily), _307_ (Temporary redirect), or _308_ (Permanent redirect).
* **Preserve query string**: Whether to preserve the query string when redirecting (disabled by default).

API information

The full syntax of the `"action_parameters"` field for a redirect rule performing a static URL redirect is the following:

```

"action_parameters": {

  "from_value": {

    "target_url": {

      "value": "<STATIC_URL_VALUE>"

    },

    "status_code": <STATUS_CODE>,

    "preserve_query_string": <BOOLEAN_VALUE>

  }

}


```

The only required parameter is `<STATIC_URL_VALUE>`.

The optional parameters can have the following values:

* `"status_code"` (integer): `301` (Moved permanently), `302` (Found, also known as Moved temporarily), `307` (Temporary redirect), or `308` (Permanent redirect).
* `"preserve_query_string"` (boolean): `true` or `false`.

## Dynamic URL redirect

Performs a dynamic URL redirect, where the target URL is determined by an expression. You can configure the redirect HTTP status code and whether to preserve the query string when redirecting.

A dynamic URL redirect has the following configuration parameters:

* **Expression**: An [expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/) that defines the target URL of the redirect. The result of evaluating this expression will be used in the `Location` HTTP header returned in the redirect response. Refer to the [fields](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/) and [functions](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/) you can use in expressions.
* **Status code**: The HTTP status code of the redirect response (_301_ by default). Must be one of the following: _301_ (Moved permanently), _302_ (Found, also known as Moved temporarily), _307_ (Temporary redirect), or _308_ (Permanent redirect).
* **Preserve query string**: Whether to preserve the query string when redirecting (disabled by default).

API information

The full syntax of the `"action_parameters"` field for a redirect rule performing a dynamic URL redirect is the following:

```

"action_parameters": {

  "from_value": {

    "target_url": {

      "expression": "<DYNAMIC_URL_EXPRESSION>"

    },

    "status_code": <STATUS_CODE>,

    "preserve_query_string": <BOOLEAN_VALUE>

  }

}


```

The only required parameter is `<DYNAMIC_URL_EXPRESSION>`.

The optional parameters can have the following values:

* `"status_code"` (integer): `301` (Moved permanently), `302` (Found, also known as Moved temporarily), `307` (Temporary redirect), or `308` (Permanent redirect).
* `"preserve_query_string"` (boolean): `true` or `false`.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/single-redirects/","name":"Single Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/single-redirects/settings/","name":"Single Redirects settings"}}]}
```

---

---
title: Create a redirect rule using Terraform
description: The following example defines a single redirect rule for a zone using Terraform. The rule creates a static URL redirect for visitors requesting the contacts page using an old URL.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/url-forwarding/single-redirects/terraform-example.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a redirect rule using Terraform

Note

Terraform code snippets below refer to the v4 SDK only.

The following example defines a single redirect rule for a zone using Terraform. The rule creates a static URL redirect for visitors requesting the contacts page using an old URL.

```

# Single Redirects resource

resource "cloudflare_ruleset" "single_redirects_example" {

  zone_id     = "<ZONE_ID>"

  name        = "redirects"

  description = "Redirects ruleset"

  kind        = "zone"

  phase       = "http_request_dynamic_redirect"


  rules {

    ref         = "redirect_old_url"

    description = "Redirect visitors still using old URL"

    expression  = "(http.request.uri.path matches \"^/contact-us/\")"

    action      = "redirect"

    action_parameters {

      from_value {

        status_code = 301

        target_url {

          value = "/contacts/"

        }

        preserve_query_string = false

      }

    }

  }

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

## Additional resources

For additional guidance on using Terraform with Cloudflare, refer to the following resources:

* [Terraform documentation](https://developers.cloudflare.com/terraform/)
* [Cloudflare Provider for Terraform ↗](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs) (reference documentation)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/url-forwarding/","name":"Redirects"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/url-forwarding/single-redirects/","name":"Single Redirects"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/url-forwarding/single-redirects/terraform-example/","name":"Create a redirect rule using Terraform"}}]}
```

---

---
title: Origin Rules
description: Origin Rules allow you to customize where the incoming traffic will go and with which parameters. Currently you can perform the following overrides:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Origin Rules

Origin Rules allow you to customize where the incoming traffic will go and with which parameters. Currently you can perform the following overrides:

* [Host header](https://developers.cloudflare.com/rules/origin-rules/features/#host-header): Overrides the `Host` header of incoming requests.
* [Server Name Indication (SNI)](https://developers.cloudflare.com/rules/origin-rules/features/#server-name-indication-sni): Overrides the Server Name Indication (SNI) value of incoming requests.
* [DNS record](https://developers.cloudflare.com/rules/origin-rules/features/#dns-record): Overrides the resolved hostname of incoming requests.
* [Destination port](https://developers.cloudflare.com/rules/origin-rules/features/#destination-port): Overrides the resolved destination port of incoming requests.

The origin rule expression will determine when these overrides will be applied.

For more complex and customized modifications, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

  
Note

Origin Rules require that you [proxy the DNS records](https://developers.cloudflare.com/dns/proxy-status/) of your domain (or subdomain) through Cloudflare.

## Rules templates

Cloudflare provides you with rules templates for common use cases.

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Templates**, and then select one of the available templates.

You can also refer to the [Examples gallery](https://developers.cloudflare.com/rules/examples/) in the developer docs.

## Availability

| Free                      | Pro | Business | Enterprise |     |
| ------------------------- | --- | -------- | ---------- | --- |
| Availability              | Yes | Yes      | Yes        | Yes |
| Number of rules           | 10  | 25       | 50         | 300 |
| Override Host header      | No  | No       | No         | Yes |
| Override SNI              | No  | No       | No         | Yes |
| Override DNS records      | No  | No       | No         | Yes |
| Override destination port | Yes | Yes      | Yes        | Yes |

## Execution order

The execution order of Rules features is the following:

* [Single Redirects](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/)
* [URL Rewrite Rules](https://developers.cloudflare.com/rules/transform/url-rewrite/)
* [Configuration Rules](https://developers.cloudflare.com/rules/configuration-rules/)
* [Origin Rules](https://developers.cloudflare.com/rules/origin-rules/)
* [Bulk Redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/)
* [Managed Transforms](https://developers.cloudflare.com/rules/transform/managed-transforms/)
* [Request Header Transform Rules](https://developers.cloudflare.com/rules/transform/request-header-modification/)
* [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/)
* [Snippets](https://developers.cloudflare.com/rules/snippets/)
* [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/)

The different types of rules listed above will take precedence over [Page Rules](https://developers.cloudflare.com/rules/page-rules/). This means that Page Rules will be overridden if there is a match for both Page Rules and the Rules products listed above.

Generally speaking, for [non-terminating actions](https://developers.cloudflare.com/ruleset-engine/rules-language/actions/) the last change made by rules in the same [phase](https://developers.cloudflare.com/ruleset-engine/about/phases/) will win (later rules can overwrite changes done by previous rules). However, for terminating actions (_Block_, _Redirect_, or one of the challenge actions), rule evaluation will stop and the action will be executed immediately.

For example, if multiple rules with the _Redirect_ action match, Cloudflare will always use the URL redirect of the first rule that matches. Also, if you configure URL redirects using different Cloudflare products (Single Redirects and Bulk Redirects), the product executed first will apply, if there is a rule match (in this case, Single Redirects).

Refer to the [Phases list](https://developers.cloudflare.com/ruleset-engine/reference/phases-list/) for the product execution order.

Warning

Using Cloudflare challenges along with Rules features may cause challenge loops. Refer to [Rules troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/) for more information.

## Important remarks

If you override the hostname with an origin rule (via `Host` header override or DNS record override) and add a header override to your load balancer configuration, the origin rule will take precedence over the load balancer configuration.

Like [Page Rules](https://developers.cloudflare.com/rules/page-rules/), an origin rule performing a `Host` header override will update the SNI value of the original request to the same value of the `Host` header. To set an SNI value different from the `Host` header override, add an SNI override in the same origin rule or create a separate origin rule for this purpose.

## Troubleshooting

When troubleshooting origin rules, use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to determine if a rule is triggering for a specific URL.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}}]}
```

---

---
title: Create an origin rule via API
description: Use the Rulesets API to create origin rules via API.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/create-api.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create an origin rule via API

Use the [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/) to create origin rules via API.

## Basic rule settings

When creating an origin rule via API, make sure you:

* Set the rule action to `route`.
* Define the [parameters](https://developers.cloudflare.com/rules/origin-rules/parameters/) in the `action_parameters` field according to the type of origin override.
* Deploy the rule to the `http_request_origin` phase at the zone level.

## Procedure

Follow this workflow to create an origin rule for a given zone via API:

1. Use the [List zone rulesets](https://developers.cloudflare.com/api/resources/rulesets/methods/list/) operation to check if there is already a ruleset for the `http_request_origin` phase at the zone level.
2. If the phase ruleset does not exist, create it using the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) operation. In the new ruleset properties, set the following values:  
   * **kind**: `zone`  
   * **phase**: `http_request_origin`
3. Use the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation to add an origin rule to the list of ruleset rules. Alternatively, include the rule in the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) request mentioned in the previous step.

Make sure your API token has the [required permissions](#required-api-token-permissions) to perform the API operations.

## Example requests

Example: Add a rule that overrides the `Host` header of incoming requests and the resolved DNS record

The following example sets the rules of an existing phase ruleset (`$RULESET_ID`) to a single origin rule — overriding the `Host` header of incoming requests and the resolved DNS record — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation. The response will contain the complete definition of the ruleset you updated.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "hr_app_overrides",

            "expression": "starts_with(http.request.uri.path, \"/hr-app/\")",

            "description": "Origin rule for the company HR application",

            "action": "route",

            "action_parameters": {

                "host_header": "hr-server.example.com",

                "origin": {

                    "host": "hr-server.example.com"

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "<RULESET_ID>",

    "name": "Origin Rules ruleset",

    "description": "Zone-level ruleset that will execute origin rules.",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "ref": "hr_app_overrides",

        "id": "<RULE_ID>",

        "version": "1",

        "action": "route",

        "action_parameters": {

          "host_header": "hr-server.example.com",

          "origin": {

            "host": "hr-server.example.com"

          }

        },

        "expression": "starts_with(http.request.uri.path, \"/hr-app/\")",

        "description": "Origin rule for the company HR application",

        "last_updated": "2022-06-03T14:42:04.219025Z",

        "ref": "<RULE_REF>"

      }

    ],

    "last_updated": "2022-06-03T14:42:04.219025Z",

    "phase": "http_request_origin"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

Example: Add a rule that overrides the port of incoming requests

The following example sets the rules of an existing phase ruleset (`$RULESET_ID`) to a single origin rule — overriding the port of incoming requests — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation. The response will contain the complete definition of the ruleset you updated.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "calendar_app_change_port",

            "expression": "starts_with(http.request.uri.path, \"/team/calendar/\")",

            "description": "Origin rule for the team calendar application",

            "action": "route",

            "action_parameters": {

                "origin": {

                    "port": 8081

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "<RULESET_ID>",

    "name": "Origin Rules ruleset",

    "description": "Zone-level ruleset that will execute origin rules.",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "ref": "calendar_app_change_port",

        "id": "<RULE_ID>",

        "version": "1",

        "action": "route",

        "action_parameters": {

          "origin": {

            "port": 8081

          }

        },

        "expression": "starts_with(http.request.uri.path, \"/team/calendar/\")",

        "description": "Origin rule for the team calendar application",

        "last_updated": "2022-06-03T14:42:04.219025Z",

        "ref": "<RULE_REF>"

      }

    ],

    "last_updated": "2022-06-03T14:42:04.219025Z",

    "phase": "http_request_origin"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

Example: Add a rule that overrides the SNI value of incoming requests

The following example sets the rules of an existing phase ruleset (`$RULESET_ID`) to a single origin rule — overriding the SNI value of incoming requests addressed at `admin.example.com` — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "override_sni_for_admin",

            "expression": "http.host eq \"admin.example.com\"",

            "description": "SNI Override for the admin area",

            "action": "route",

            "action_parameters": {

                "sni": {

                    "value": "sni.example.com"

                }

            }

        }

    ]

  }'


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

---

## Required API token permissions

The API token used in API requests to manage origin rules must have at least the following permission:

* _Zone_ \> _Origin Rules_ \> _Edit_

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/origin-rules/create-api/","name":"Create an origin rule via API"}}]}
```

---

---
title: Create an origin rule in the dashboard
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/create-dashboard.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create an origin rule in the dashboard

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Create rule** \> **Origin Rule**.
3. (Optional) Select one of the rule templates that address common use cases. Then, review and adjust the proposed rule configuration.
4. Enter a descriptive name for the rule in **Rule name**.
5. Under **When incoming requests match**, define the [rule expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/).
6. Under **Set origin parameters**, define the [origin rule settings](https://developers.cloudflare.com/rules/origin-rules/features/) you wish to change for requests matching the rule expression.
7. To save and deploy your rule, select **Deploy**. If you are not ready to deploy your rule, select **Save as Draft**.  
If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to [Troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/#this-rule-may-not-apply-to-your-traffic) for more information.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/origin-rules/create-dashboard/","name":"Create an origin rule in the dashboard"}}]}
```

---

---
title: Origin Rules examples
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/examples/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Origin Rules examples

[Change the HTTP Host header and DNS recordCreate an origin rule to change the HTTP Host header and the resolved DNS record.](https://developers.cloudflare.com/rules/origin-rules/examples/change-http-host-header/)[Change the destination portCreate an origin rule to change the destination port.](https://developers.cloudflare.com/rules/origin-rules/examples/change-port/)[Define a single origin rule using TerraformCreate an origin rule using Terraform to override the Host header, the resolved hostname, and the destination port of API requests.](https://developers.cloudflare.com/rules/origin-rules/examples/define-single-origin-terraform/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/origin-rules/examples/","name":"Origin Rules examples"}}]}
```

---

---
title: Change the HTTP Host header and DNS record
description: Create an origin rule to change the HTTP `Host` header and the resolved DNS record.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/examples/change-http-host-header.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Change the HTTP Host header and DNS record

Create an origin rule to change the HTTP `Host` header and DNS record.

The following origin rule overrides the HTTP `Host` header to `hr-server.example.com` for all requests with a URI path starting with `/hr-app/`. It also overrides the DNS record to the same hostname.

The `Host` header override only updates the header value; the DNS record override will handle the rerouting of incoming requests. For more information on these overrides, refer to [Origin Rules settings](https://developers.cloudflare.com/rules/origin-rules/features/).

* [ Dashboard ](#tab-panel-6005)
* [ API ](#tab-panel-6006)

Expression when using the Expression Builder:

| Field    | Operator    | Value    |
| -------- | ----------- | -------- |
| URI Path | starts with | /hr-app/ |

Expression when using the Expression Editor:

```

(starts_with(http.request.uri.path, "/hr-app/"))


```

Value after **Host Header** \> **Rewrite to**:

```

hr-server.example.com


```

Value after **DNS Record** \> **Override to**:

```

hr-server.example.com


```

The following example sets the rules of an existing phase ruleset (`$RULESET_ID`) to a single origin rule — overriding the `Host` header of incoming requests and the resolved DNS record — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation. The response will contain the complete definition of the ruleset you updated.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "hr_app_overrides",

            "expression": "starts_with(http.request.uri.path, \"/hr-app/\")",

            "description": "Origin rule for the company HR application",

            "action": "route",

            "action_parameters": {

                "host_header": "hr-server.example.com",

                "origin": {

                    "host": "hr-server.example.com"

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "<RULESET_ID>",

    "name": "Origin Rules ruleset",

    "description": "Zone-level ruleset that will execute origin rules.",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "ref": "hr_app_overrides",

        "id": "<RULE_ID>",

        "version": "1",

        "action": "route",

        "action_parameters": {

          "host_header": "hr-server.example.com",

          "origin": {

            "host": "hr-server.example.com"

          }

        },

        "expression": "starts_with(http.request.uri.path, \"/hr-app/\")",

        "description": "Origin rule for the company HR application",

        "last_updated": "2022-06-03T14:42:04.219025Z",

        "ref": "<RULE_REF>"

      }

    ],

    "last_updated": "2022-06-03T14:42:04.219025Z",

    "phase": "http_request_origin"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/origin-rules/examples/","name":"Origin Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/origin-rules/examples/change-http-host-header/","name":"Change the HTTP Host header and DNS record"}}]}
```

---

---
title: Change the destination port
description: Create an origin rule to change the destination port.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/examples/change-port.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Change the destination port

Create an origin rule to change the destination port.

The following origin rule overrides the destination port to `8081` for all requests where the URI path starts with `/team/calendar/`.

* [ Dashboard ](#tab-panel-6007)
* [ API ](#tab-panel-6008)

Text in Expression Editor:

```

starts_with(http.request.uri.path, "/team/calendar/")


```

Value after **Destination Port** \> **Rewrite to**:

```

8081


```

The following example sets the rules of an existing phase ruleset (`$RULESET_ID`) to a single origin rule — overriding the port of incoming requests — using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation. The response will contain the complete definition of the ruleset you updated.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "calendar_app_change_port",

            "expression": "starts_with(http.request.uri.path, \"/team/calendar/\")",

            "description": "Origin rule for the team calendar application",

            "action": "route",

            "action_parameters": {

                "origin": {

                    "port": 8081

                }

            }

        }

    ]

  }'


```

```

{

  "result": {

    "id": "<RULESET_ID>",

    "name": "Origin Rules ruleset",

    "description": "Zone-level ruleset that will execute origin rules.",

    "kind": "zone",

    "version": "2",

    "rules": [

      {

        "ref": "calendar_app_change_port",

        "id": "<RULE_ID>",

        "version": "1",

        "action": "route",

        "action_parameters": {

          "origin": {

            "port": 8081

          }

        },

        "expression": "starts_with(http.request.uri.path, \"/team/calendar/\")",

        "description": "Origin rule for the team calendar application",

        "last_updated": "2022-06-03T14:42:04.219025Z",

        "ref": "<RULE_REF>"

      }

    ],

    "last_updated": "2022-06-03T14:42:04.219025Z",

    "phase": "http_request_origin"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/origin-rules/examples/","name":"Origin Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/origin-rules/examples/change-port/","name":"Change the destination port"}}]}
```

---

---
title: Define a single origin rule using Terraform
description: Create an origin rule using Terraform to override the `Host` header, the resolved hostname, and the destination port of API requests.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/examples/define-single-origin-terraform.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Define a single origin rule using Terraform

Create an origin rule using Terraform to override the `Host` header, the resolved hostname, and the destination port of API requests.

Note

Terraform code snippets below refer to the v4 SDK only.

The following example defines a single origin rule for a zone using Terraform. The rule overrides the `Host` header, the resolved hostname, and the destination port of API requests.

```

# Change origin for API requests

resource "cloudflare_ruleset" "http_origin_example" {

  zone_id     = "<ZONE_ID>"

  name        = "Change origin"

  description = ""

  kind        = "zone"

  phase       = "http_request_origin"


  rules {

    ref         = "change_api_origin"

    description = "Change origin of API requests"

    expression  = "(http.request.uri.path matches \"^/api/\")"

    action      = "route"

    action_parameters {

      host_header = "example.net"

      origin {

        host = "example.net"

        port = 8000

      }

    }

  }

}


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

## Additional resources

For additional guidance on using Terraform with Cloudflare, refer to the following resources:

* [Terraform documentation](https://developers.cloudflare.com/terraform/)
* [Cloudflare Provider for Terraform ↗](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs) (reference documentation)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/origin-rules/examples/","name":"Origin Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/origin-rules/examples/define-single-origin-terraform/","name":"Define a single origin rule using Terraform"}}]}
```

---

---
title: Origin Rules FAQ
description: Below you will find answers to the most commonly asked questions regarding Origin Rules.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/faq.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Origin Rules FAQ

Below you will find answers to the most commonly asked questions regarding Origin Rules.

## What happens if I use both an origin rule and a page rule to perform a Host header/DNS record override?

In this situation the origin rule parameters will override the [page rule](https://developers.cloudflare.com/rules/page-rules/) parameters.

Consider the following example scenarios:

* A page rule defines a Host header override, but not a resolve override (or DNS record override). An origin rule defines a DNS record override, but not a Host header override. The resulting request will have the `Host` header defined by the page rule and the origin hostname defined by the origin rule.
* A page rule defines a Host header override, and an origin rule also defines a Host header override. The resulting request will have the `Host` header defined by the origin rule.

## Will Cloudflare automatically migrate my Page Rules with Host header and DNS record overrides to origin rules?

Yes. Refer to the [Page Rules migration guide](https://developers.cloudflare.com/rules/reference/page-rules-migration/) for any updates on the migration process.

## What happens if more than one origin rule matches the current request?

If two or more origin rules match a request, the configuration of those rules is merged. While merging two configurations, the settings of later rules will override the settings defined in previous rules, updating or adding configuration properties. The final configuration applied by Cloudflare will be this merged version.

For example, if you configure the following two [origin rules](https://developers.cloudflare.com/rules/origin-rules/) and both rules match, Cloudflare will use the destination port set by the first rule, and the DNS hostname override and `Host` header value set by the second rule.

**Origin rule #1**

| Parameter            | Value       |
| -------------------- | ----------- |
| Set Host header      | example.com |
| Set destination port | 8081        |

**Origin rule #2**

| Parameter        | Value       |
| ---------------- | ----------- |
| Set Host header  | example.net |
| Set DNS hostname | example.net |

JSON example for API users

When [using the API](https://developers.cloudflare.com/rules/origin-rules/create-api/), you configure origin rule parameters in an `action_parameters` object.

```

{

  "rules": [

    {

      "expression": "http.request.uri.query contains \"/eu/\"",

      "description": "Origin rule #1",

      "action": "route",

      "action_parameters": {

        "host_header": "example.com",

        "origin": {

          "port": 8081

        }

      }

    },

    {

      "expression": "http.request.uri.query contains \"/eu/\"",

      "description": "Origin rule #2",

      "action": "route",

      "action_parameters": {

        "host_header": "example.net",

        "origin": {

          "host": "example.net"

        }

      }

    }

  ]

}


```

The merged configuration to apply would be the following:

| Parameter            | Value       |
| -------------------- | ----------- |
| Set Host header      | example.net |
| Set destination port | 8081        |
| Set DNS hostname     | example.net |

If you also configured a destination port in rule #2, that value would override the `8081` destination port defined in rule #1.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/origin-rules/faq/","name":"Origin Rules FAQ"}}]}
```

---

---
title: Origin Rules settings
description: The following sections describe the available settings in Origin Rules.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/features.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Origin Rules settings

The following sections describe the available settings in Origin Rules.

## Host header

Allows you to rewrite the HTTP `Host` header of incoming requests.

A common use case for this functionality is when your content is hosted on a third-party server that only accepts `Host` headers with their own server names. In this situation, you must update the `Host` HTTP header in incoming requests from `Host: example.com` to `Host: thirdpartyserver.example.net`.

Notes

* In most situations, when you rewrite the HTTP `Host` header you also need to configure a [DNS record override](#dns-record). The `Host` header override only updates the header value; the DNS record override will handle the rerouting of the request.
* An origin rule performing a `Host` header override will also update the Server Name Indication (SNI) value of the original request to the same value. To set an SNI value different from the `Host` header value, add an [SNI override](#server-name-indication-sni) in the same origin rule or create a separate origin rule for this purpose.
* If you have configured load balancing through Cloudflare and you wish to override the HTTP `Host` header per origin or for a given monitor, refer to [Override HTTP Host headers](https://developers.cloudflare.com/load-balancing/additional-options/override-http-host-headers/) in the Load Balancing documentation for more information.
* When an origin rule is configured to override the `Host` header for a request handled by a [Worker](https://developers.cloudflare.com/workers/), this override is not taken into account when evaluating [Workers routes](https://developers.cloudflare.com/workers/configuration/routing/routes/).

## Server Name Indication (SNI)

Allows you to override the Server Name Indication (SNI) [1](#user-content-fn-1) value of a request. For more information, refer to [What is SNI (Server Name Indication)? ↗](https://www.cloudflare.com/learning/ssl/what-is-sni/) in the Learning Center.

Notes

* The new SNI value must be a valid hostname on the same Cloudflare account (possibly on a different zone).
* Currently, you can only use a static value when overriding SNI.
* An SNI override will take precedence over [SNI rewrites of custom origins](https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/start/advanced-settings/custom-origin/#sni-rewrites) when using Cloudflare for SaaS.

## DNS record

Allows you to override the resolved hostname of incoming requests. This functionality is also known as resolve override.

A common use case is when you are serving an application from the URI (for example, `mydomain.com/app`). In this case, the `app` may be hosted on a different server or by a third party. A DNS record override allows you to redirect requests to this endpoint to the server for that third-party application.

Note

* You must specify a valid hostname in a DNS record override that is a hostname on the same Cloudflare account (possibly on a different zone). You can [configure a DNS record](https://developers.cloudflare.com/dns/manage-dns-records/how-to/create-dns-records#create-dns-records) (a `CNAME`, `A`, or `AAAA` record) with a hostname pointing to a third-party hostname/IP address, either proxied by Cloudflare or not.
* In most situations, when you configure a DNS record override you also need to configure a [Host header override](#host-header). The DNS record override handles the rerouting of the request; the `Host` header override updates the `Host` HTTP header value in the request. Defining a `Host` header override will also update the Server Name Indication (SNI) value of the original request to the same value. To set an SNI value different from the `Host` header value, add an [SNI override](#server-name-indication-sni) in the same origin rule or create a separate origin rule for this purpose.

The following example DNS records configure a `resolve.example.com` hostname pointing to an external hostname and IP address using a `CNAME` record and an `A` record, respectively:

**Example `CNAME` record**

* **Type:** _CNAME_
* **Name:** `resolve.example.com`
* **Target:** `domain.s3.amazonaws.com`
* **TTL:** `Auto`
* **Proxy status:** _Proxied_ (orange cloud icon)

**Example `A` record**

* **Type:** _A_
* **Name:** `resolve.example.com`
* **IPv4 address:** `203.0.113.1`
* **TTL:** `Auto`
* **Proxy status:** _Proxied_ (orange cloud icon)

## Destination port

Allows you to override the destination port of a request.

When you configure a destination port override, you can redirect incoming requests to a different port. For example, you could override the destination port for requests received for `mydomain.com` so that they are served by the application running on port 9000 (`mydomain.com:9000`).

The destination port must be between 1 and 65,535.

## Footnotes

1. SNI allows a server to host multiple TLS Certificates for multiple websites using a single IP address. SNI adds the website hostname in the TLS handshake to inform the server which website to present when using shared IPs. [↩](#user-content-fnref-1)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/origin-rules/features/","name":"Origin Rules settings"}}]}
```

---

---
title: Origin Rules API parameter reference
description: Create different overrides by including different action parameters in the action_parameters field:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/parameters.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Origin Rules API parameter reference

Create [different overrides](https://developers.cloudflare.com/rules/origin-rules/features/) by including different action parameters in the `action_parameters` field:

| Override type                                   | What to include                                                                |
| ----------------------------------------------- | ------------------------------------------------------------------------------ |
| Host header override                            | [host\_header parameter](#host-header-override-parameters)                     |
| SNI override                                    | [sni object](#sni-override-parameters)                                         |
| DNS record override / Destination port override | [origin object](#dns-record-override-and-destination-port-override-parameters) |

Note

The same origin rule can have different types of overrides. Refer to [Configuring several overrides in the same rule](#configuring-several-overrides-in-the-same-rule) for a syntax example.

## Host header override parameters

The full syntax of the `action_parameters` field for overriding the HTTP `Host` header is the following:

```

"action_parameters": {

  "host_header": "<HOST_HEADER_VALUE>"

}


```

## SNI override parameters

The full syntax of the `action_parameters` field for overriding the SNI value of incoming requests is the following:

```

"action_parameters": {

  "sni": {

    "value": "<SNI_VALUE>"

  }

}


```

## DNS record override and destination port override parameters

The full syntax of the `action_parameters` field for overriding both the hostname and the destination port of incoming requests is the following:

```

"action_parameters": {

  "origin": {

    "host": "<HOSTNAME>",

    "port": <PORT>

  }

}


```

If you are only overriding the hostname or the port, omit the `port` or `host` parameter, respectively.

## Configuring several overrides in the same rule

The same origin rule can have different types of overrides. For example, a single origin rule can perform an HTTP `Host` header override and a destination port override. The syntax of such a rule would be the following:

```

"action_parameters": {

  "host_header": "<HOST_HEADER_VALUE>",

  "origin": {

    "port": <PORT>

  }

}


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/origin-rules/parameters/","name":"Origin Rules API parameter reference"}}]}
```

---

---
title: Origin Rules tutorials
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/tutorials/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Origin Rules tutorials

| Name                                                                                                                                             | Last Updated     | Difficulty |
| ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | ---------- |
| [Point to Pages with a custom domain](https://developers.cloudflare.com/rules/origin-rules/tutorials/point-to-pages-with-custom-domain/)         | 12 months ago    | Beginner   |
| [Point to R2 bucket with a custom domain](https://developers.cloudflare.com/rules/origin-rules/tutorials/point-to-r2-bucket-with-custom-domain/) | 12 months ago    | Beginner   |
| [Change URI path and Host header](https://developers.cloudflare.com/rules/origin-rules/tutorials/change-uri-path-and-host-header/)               | about 1 year ago | Beginner   |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/origin-rules/tutorials/","name":"Origin Rules tutorials"}}]}
```

---

---
title: Change URI path and Host header
description: This tutorial shows you how to modify both the URI path and the Host header of incoming requests using Transform Rules and Origin Rules.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/tutorials/change-uri-path-and-host-header.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Change URI path and Host header

**Last reviewed:**  about 1 year ago 

This tutorial will instruct you how to modify both the URI path and the `Host` header of incoming requests using [Transform Rules](https://developers.cloudflare.com/rules/transform/) and Origin Rules.

Your website visitors will be routed from `https://<YOUR_SOURCE_HOSTNAME>/uploads/*` to `https://<YOUR_TARGET_HOSTNAME>/*`.

In this tutorial you will do the following:

1. Create a URL rewrite to remove `/uploads` from the path.
2. Create an origin rule to modify the `Host` header to desired hostname.

By following these steps, you can effectively manage both URI paths and `Host` headers to route traffic appropriately and optimize request handling.

## 1\. Create a URL rewrite

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Create rule** \> **URL Rewrite Rule**.
3. Enter a descriptive name for the rule in **Rule name**.
4. Under **If incoming requests match**, select **Custom filter expression**, select **Edit expression**, and enter the following expression:  
Text in **Expression Editor**:  
```  
raw.http.request.uri.path matches "^/uploads/.*"  
```
5. Under **Set Rewrite parameters**, select **Path** \> **Rewrite to**, and select _Dynamic_.
6. Define the action for your rewrite URL rule:  
Text after **Path** \> **Rewrite to** \> _Dynamic_:  
```  
regex_replace(raw.http.request.uri.path, "^/uploads/", "/")  
```  
The [regex\_replace()](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#regex%5Freplace) function replaces the `/uploads/` part of the path with `/`, changing `/uploads/example.jpg` to `/example.jpg`.
7. Select **Deploy**.

## 2\. Create an origin rule

Note

If you are routing traffic to an object storage bucket, use [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/) instead of an origin rule.

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Create rule** \> **Origin Rule**.
3. Enter a descriptive name for the rule in **Rule name**.
4. Under **When incoming requests match**, define the rule expression:  
Text in **Expression Editor**:  
```  
raw.http.request.uri.path matches "^/uploads/.*"  
```
5. Under **Set origin parameters**, select **Host Header** \> **Rewrite to**.
6. Configure the rule to modify the `Host` header to desired hostname:  
Text after **Host Header** \> **Rewrite to**:  
```  
example.com  
```  
This will set the [Host header](https://developers.cloudflare.com/rules/origin-rules/features/#host-header) to `example.com` for matching requests. Make sure to replace `example.com` with your actual hostname.
7. (Optional) To route requests to a different origin (DNS target), use [DNS override](https://developers.cloudflare.com/rules/origin-rules/features/#dns-record):  
Text after **DNS Record** \> **Override to**:  
```  
example.com  
```  
This will route requests to the DNS target of `example.com` instead of your default [DNS record](https://developers.cloudflare.com/dns/manage-dns-records/how-to/create-dns-records/).
8. Select **Deploy**.

## Final remarks

After completing this tutorial, incoming traffic for `https://<YOUR_SOURCE_HOSTNAME>/uploads/*` will be routed to `https://<YOUR_TARGET_HOSTNAME>/*`.

Ensure the filters for the [URL rewrite](https://developers.cloudflare.com/rules/transform/url-rewrite/) and the [origin rule](https://developers.cloudflare.com/rules/origin-rules/) (or [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/) rule) are precise to avoid unintended rule executions.

Remember that rules are evaluated [in sequence](https://developers.cloudflare.com/ruleset-engine/reference/phases-list/), so Transform Rules (including URL rewrites) run before Origin Rules or Cloud Connector.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/origin-rules/tutorials/","name":"Origin Rules tutorials"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/origin-rules/tutorials/change-uri-path-and-host-header/","name":"Change URI path and Host header"}}]}
```

---

---
title: Point to Pages with a custom domain
description: This tutorial will instruct you how to configure an origin rule and a DNS record to point to a Pages deployment with a custom domain.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/tutorials/point-to-pages-with-custom-domain.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Point to Pages with a custom domain

**Last reviewed:**  12 months ago 

This tutorial will instruct you how to configure an origin rule and a DNS record to point to a Pages deployment with a custom domain.

The procedure will use the following example values:

| URL that website visitors will access | mycustomerexample.com/blog/\* |
| ------------------------------------- | ----------------------------- |
| Zone domain                           | mycustomerexample.com         |
| Cloudflare Pages subdomain            | myblog.pages.dev              |
| Cloudflare Pages custom domain        | blogmirror.example.com        |

When configuring your Pages custom domain, use a custom domain that you do not plan to use in production (`blogmirror.example.com` in this example).

## 1\. Configure custom domain in your Pages project

To add the custom domain to your Pages deployment:

1. In the Cloudflare dashboard, go to the **Workers & Pages** page.  
[ Go to **Workers & Pages** ](https://dash.cloudflare.com/?to=/:account/workers-and-pages)
2. Select your Pages project.
3. Go to **Custom domains**.
4. Select **Set up a custom domain**.
5. Enter `blogmirror.example.com` and select **Continue**.

When you add the custom domain to your Pages deployment, Cloudflare automatically creates a `CNAME` DNS record for the custom domain.

## 2\. Create origin rule to rewrite host header and override DNS record

In your `mycustomerexample.com` zone, create an origin rule with the following configuration:

**If incoming requests match**

| Field    | Operator | Value    |
| -------- | -------- | -------- |
| URI Path | wildcard | /blog/\* |

If using the Expression Editor, enter the following expression:

```

(http.request.uri.path wildcard "/blog/*")


```

**Set origin parameters**

* Value after **Host header** \> **Rewrite to**: `blogmirror.example.com`
* Value after **DNS record** \> **Override to**: `blogmirror.example.com`

## 3\. (Optional) Configure URL rewrite

In this example, the URL that website visitors will access starts with `/blog`. However, the Pages deployment does not have this initial URL segment.

Use a URL rewrite to remove the `/blog` segment from the URL path.

1. Go to **Rules** \> **Overview**.
2. Select **Create rule** \> **URL Rewrite Rule**.
3. Enter a descriptive name for the rule in **Rule name**.
4. In **If incoming requests match**, select **Wildcard pattern**.
5. Enter the following value in **Request URL**:  
```  
https://<YOUR_HOSTNAME>/blog/*  
```  
In the current example, the value would be `https://mycustomerexample.com/blog/*`.
6. In **Then rewrite the path and/or query**, enter the following values under **Path**:  
| Target path   | Rewrite to |  
| ------------- | ---------- |  
| \[/\] blog/\* | \[/\] ${1} |
7. Select **Deploy**.

Note

Cloudflare provides a rule template in the dashboard called **Rewrite Path for Object Storage Bucket** that you can use and adapt to configure the URL rewrite rule.

## More resources

* [Tutorial: Change URI Path and Host Header](https://developers.cloudflare.com/rules/origin-rules/tutorials/change-uri-path-and-host-header/)
* [Cloudflare Pages: Custom domains](https://developers.cloudflare.com/pages/configuration/custom-domains/)
* [DNS records](https://developers.cloudflare.com/dns/manage-dns-records/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/origin-rules/tutorials/","name":"Origin Rules tutorials"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/origin-rules/tutorials/point-to-pages-with-custom-domain/","name":"Point to Pages with a custom domain"}}]}
```

---

---
title: Point to R2 bucket with a custom domain
description: This tutorial will instruct you how to configure an origin rule and a DNS record to point to an R2 bucket configured with a custom domain.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/origin-rules/tutorials/point-to-r2-bucket-with-custom-domain.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Point to R2 bucket with a custom domain

**Last reviewed:**  12 months ago 

This tutorial will instruct you how to configure an origin rule and a DNS record to point to an R2 bucket configured with a custom domain.

The procedure will use the following example values:

| URL that website visitors will access | mycustomerexample.com/images/\* |
| ------------------------------------- | ------------------------------- |
| R2 bucket custom domain               | imagesbucket.example.com        |

When configuring your R2 bucket's custom domain, use a custom domain that you do not plan to use in production (`imagesbucket.example.com` in this example).

## 1\. Configure custom domain in your Pages project

1. In the Cloudflare dashboard, go to the **R2 object storage** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/r2/overview)
2. Select your bucket.
3. On the bucket page, select **Settings**.
4. Under **Public access** \> **Custom Domains**, select **Connect Domain**.
5. Enter the domain name you want to connect to — `imagesbucket.example.com` in this example — and select **Continue**.
6. Review the new record that will be added to the DNS table and select **Connect Domain**.

Your domain is now connected. The status takes a few minutes to change from **Initializing** to **Active**, and you may need to refresh to review the status update. If the status has not changed, select the **...** next to your bucket and select **Retry connection**.

To view the added DNS record, select **...** next to the connected domain and select **Manage DNS**.

Note

The domain used must belong to the same account as the R2 bucket.

## 2\. Create origin rule to rewrite host header and override DNS record

In your `mycustomerexample.com` zone, create an origin rule with the following configuration:

**If incoming requests match**

| Field    | Operator | Value      |
| -------- | -------- | ---------- |
| URI Path | wildcard | /images/\* |

If using the Expression Editor, enter the following expression:

```

(http.request.uri.path wildcard "/images/*")


```

**Set origin parameters**

* Value after **Host header** \> **Rewrite to**: `imagesbucket.example.com`
* Value after **DNS record** \> **Override to**: `imagesbucket.example.com`

## 3\. (Optional) Configure URL rewrite

In our example, the URL that website visitors will access starts with `/images`. However, images stored in the example R2 bucket do not have this initial URL segment.

Use a URL rewrite to remove the `/images` segment from the URL path. Cloudflare provides a rule template in the dashboard called **Rewrite Path for Object Storage Bucket** that you can use to configure the required rewrite.

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Create rule** \> **URL Rewrite Rule**.
3. Enter a descriptive name for the rule in **Rule name**.
4. In **If incoming requests match**, select **Wildcard pattern**.
5. Enter the following value in **Request URL**:  
```  
https://<YOUR_HOSTNAME>/images/*  
```  
In the current example, the value would be `https://mycustomerexample.com/images/*`.
6. In **Then rewrite the path and/or query**, enter the following values under **Path**:  
| Target path     | Rewrite to |  
| --------------- | ---------- |  
| \[/\] images/\* | \[/\] ${1} |
7. Select **Deploy**.

Note

Cloudflare provides a rule template in the dashboard called **Rewrite Path for Object Storage Bucket** that you can use and adapt to configure the URL rewrite rule.

## More resources

* [Tutorial: Change URI Path and Host Header](https://developers.cloudflare.com/rules/origin-rules/tutorials/change-uri-path-and-host-header/)
* [Cloudflare R2: Public buckets](https://developers.cloudflare.com/r2/buckets/public-buckets/)
* [DNS records](https://developers.cloudflare.com/dns/manage-dns-records/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/origin-rules/","name":"Origin Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/origin-rules/tutorials/","name":"Origin Rules tutorials"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/origin-rules/tutorials/point-to-r2-bucket-with-custom-domain/","name":"Point to R2 bucket with a custom domain"}}]}
```

---

---
title: Cache Rules
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/link-cache-rules.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cache Rules

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/link-cache-rules/","name":"Cache Rules"}}]}
```

---

---
title: Cloud Connector
description: Cloud Connector (Beta) allows you to route matching incoming traffic from your website to a public cloud provider that you define: Cloudflare R2 object storage or an external provider such as AWS, Google Cloud, and Azure. With Cloud Connector you can make Cloudflare the control center for your web traffic, including traffic served from public cloud providers, without having to configure additional rules.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/cloud-connector/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cloud Connector

Cloud Connector (Beta) allows you to route matching incoming traffic from your website to a public cloud provider that you define: [Cloudflare R2](https://developers.cloudflare.com/r2/) object storage or an external provider such as AWS, Google Cloud, and Azure. With Cloud Connector you can make Cloudflare the control center for your web traffic, including traffic served from public cloud providers, without having to configure additional rules.

Note

Cloud Connector requires that you [proxy the DNS records](https://developers.cloudflare.com/dns/proxy-status/) of your domain (or subdomain) through Cloudflare.

## How it works

First, you configure a Cloud Connector rule that specifies:

* The cloud provider and a supported cloud service that will accept traffic.
* The traffic that will be routed to that cloud service.

Then, Cloudflare will create the [necessary configurations](#applied-configurations) so that the content is accessible for requests matching your Cloud Connector rule. Your object storage bucket should be public for Cloud Connector to work.

Cloud Connector rules are evaluated last in the request evaluation workflow. When there is a rule match and you have other rules changing the same settings, the Cloud Connector rule will win over other rules.

## Applied configurations

Cloud Connector will perform the following configurations automatically, depending on the cloud provider:

* Modify the `Host` header.
* Adjust SSL/TLS for bucket-related traffic ([AWS S3 website endpoints](https://developers.cloudflare.com/rules/cloud-connector/providers/#ssl-connections-to-aws-s3-endpoints) only).

Additional configurations you may need

Cloud Connector will not apply any of the following configurations:

* **Cache content served from storage bucket**: To define custom cache behavior — like when to cache returned objects and for [how long](https://developers.cloudflare.com/cache/how-to/cache-rules/settings/#edge-ttl) — you will need to create a [cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/). For an example rule configuration, refer to [Cache Level (Cache Everything)](https://developers.cloudflare.com/cache/how-to/cache-rules/examples/cache-everything/).
* **Create URL rewrites**: To adjust the URL structure from what your website visitors use to obtain a resource and the folder structure being used in the storage bucket, you will need to create a [URL rewrite](https://developers.cloudflare.com/rules/transform/url-rewrite/). For example, you could create a URL rewrite to remove the `/files` prefix from URI paths before routing the request to your object storage bucket. For an example configuration, refer to [Rewrite path for object storage bucket](https://developers.cloudflare.com/rules/transform/examples/rewrite-path-object-storage/).

## Availability

Cloud Connector is available in beta to all customers. The maximum number of rules depends on your Cloudflare plan:

| Free            | Pro | Business | Enterprise |     |
| --------------- | --- | -------- | ---------- | --- |
| Availability    | Yes | Yes      | Yes        | Yes |
| Number of rules | 10  | 25       | 50         | 300 |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/cloud-connector/","name":"Cloud Connector"}}]}
```

---

---
title: Configure a Cloud Connector rule via API
description: You can configure Cloud Connector rules using the Cloudflare API.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/cloud-connector/create-api.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Configure a Cloud Connector rule via API

You can configure Cloud Connector rules using the [Cloudflare API](https://developers.cloudflare.com/fundamentals/api/).

## Required permissions

The [API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) used in API requests to manage Cloud Connector rules must have at least the following permission:

* _Zone_ \> _Cloud Connector_ \> _Write_

Note

A token with this permission is only valid for the Cloud Connector endpoints described in this page. You cannot use it to interact with the `http_cloud_connector` phase via [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/).

## Endpoints

To obtain the complete endpoint, append the Cloud Connector endpoints listed below to the Cloudflare API base URL:

```

https://api.cloudflare.com/client/v4


```

The `{zone_id}` argument is the [zone ID](https://developers.cloudflare.com/fundamentals/account/find-account-and-zone-ids/) (a hexadecimal string). You can find this value in the Cloudflare dashboard.

The following table summarizes the available operations.

| Operation                                  | Verb + Endpoint                              |
| ------------------------------------------ | -------------------------------------------- |
| List Cloud Connector rules                 | GET /zones/{zone\_id}/cloud\_connector/rules |
| Create/update/delete Cloud Connector rules | PUT /zones/{zone\_id}/cloud\_connector/rules |

## Example API calls

### List of Cloud Connector rules

The following example returns a list of existing Cloud Connector rules:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Cloud Connector Read`
* `Cloud Connector Write`

Rules

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cloud_connector/rules" \

  --request GET \

  --header "X-Auth-Email: $CLOUDFLARE_EMAIL" \

  --header "X-Auth-Key: $CLOUDFLARE_API_KEY"


```

```

{

  "result": [

    {

      "id": "<RULE_1_ID>",

      "provider": "aws_s3",

      "expression": "http.request.uri.path wildcard \"/images/*\"",

      "description": "Connect to S3 bucket containing images",

      "enabled": true,

      "parameters": {

        "host": "examplebucketwithimages.s3.north-eu.amazonaws.com"

      }

    }

  ],

  "success": true,

  "errors": [],

  "messages": []

}


```

### Create/update/delete Cloud Connector rules

Warning

To create a new rule and keep all existing rules, you must include them all in your request body. Omitting an existing rule in the request body will delete the corresponding Cloud Connector rule.

The following example request will replace all existing Cloud Connector rules with a single rule:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Cloud Connector Write`

Put Rules

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/cloud_connector/rules" \

  --request PUT \

  --header "X-Auth-Email: $CLOUDFLARE_EMAIL" \

  --header "X-Auth-Key: $CLOUDFLARE_API_KEY" \

  --json '[

    {

        "expression": "http.request.uri.path wildcard \"/images/*\"",

        "provider": "cloudflare_r2",

        "description": "Connect to R2 bucket containing images",

        "parameters": {

            "host": "mybucketcustomdomain.example.com"

        }

    }

  ]'


```

The required body parameters for each rule are: `expression`, `provider`, and `parameters.host`.

The `provider` value must be one of the following: `cloudflare_r2`, `aws_s3`, `azure_storage`, and `gcp_storage`.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/cloud-connector/","name":"Cloud Connector"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/cloud-connector/create-api/","name":"Configure a Cloud Connector rule via API"}}]}
```

---

---
title: Configure a Cloud Connector rule in the dashboard
description: To configure a Cloud Connector rule in the dashboard:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/cloud-connector/create-dashboard.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Configure a Cloud Connector rule in the dashboard

To configure a Cloud Connector rule in the dashboard:

1. In the Cloudflare dashboard, go to the **Cloud Connector** page.  
[ Go to **Cloud Connector** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/cloud-connector)
2. Select your [cloud provider](https://developers.cloudflare.com/rules/cloud-connector/providers/) (Cloudflare R2 or an external provider).
3. If you selected Cloudflare R2 in the previous step, select your bucket and your custom domain, and select **Next**.  
If you selected a different storage provider, enter the bucket URL and select **Next**.  
Warning  
The bucket URL must follow a [specific format](https://developers.cloudflare.com/rules/cloud-connector/providers/) according to your provider.
4. Enter a descriptive name for the rule in **Cloud Connector name**.
5. Under **If**, select **Custom filter expression** and [enter an expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/) to define the traffic that will be redirected to the bucket. For example:  
   * To route all requests matching `http*://example.com/images/*` (HTTPS and HTTP requests) you could enter the following expression:  
   `http.request.full_uri wildcard "http*://example.com/images/*"`  
   * To route all requests matching `http*://images.example.com/*` (HTTPS and HTTP requests) you could enter the following expression:  
   `http.request.full_uri wildcard "http*://images.example.com/*"`  
Alternatively, select **All incoming requests** to redirect all incoming traffic for your zone to the storage bucket you selected.
6. To save and deploy your rule, select **Deploy**. If you are not ready to deploy the rule, select **Save as Draft**.  
If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to [Troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/#this-rule-may-not-apply-to-your-traffic) for more information.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/cloud-connector/","name":"Cloud Connector"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/cloud-connector/create-dashboard/","name":"Configure a Cloud Connector rule in the dashboard"}}]}
```

---

---
title: Configure Cloud Connector rules using Terraform
description: You can create Cloud Connector rules using the Terraform Cloudflare provider.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/cloud-connector/create-terraform.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Configure Cloud Connector rules using Terraform

You can create Cloud Connector rules using the [Terraform Cloudflare provider ↗](https://registry.terraform.io/providers/cloudflare/cloudflare/latest).

To get started with Terraform for Cloudflare configuration, refer to [Get started](https://developers.cloudflare.com/terraform/installing/).

## Required permissions

The [API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) used by Terraform must have at least the following permission:

* _Zone_ \> _Cloud Connector_ \> _Write_

## Example configuration

Note

Terraform code snippets below refer to the v4 SDK only.

The following example Terraform configuration creates Cloud Connector rules for various [supported providers](https://developers.cloudflare.com/rules/cloud-connector/providers/) to route traffic between them based on URI paths:

```

resource "cloudflare_cloud_connector_rules" "cloud_connector_rules" {

  zone_id = "<ZONE_ID>"


  rules {

    description = "Route /data to GCP bucket"

    enabled     = true

    expression  = "(http.request.uri.path wildcard \"*/data/*\")"

    provider    = "gcp_storage"

    parameters {

      host = "mystorage.storage.googleapis.com"

    }

  }


  rules {

    description = "Route /resources to AWS bucket"

    enabled     = true

    expression  = "(http.request.uri.path wildcard \"*/resources/*\")"

    provider    = "aws_s3"

    parameters {

      host = "mystorage.s3.ams.amazonaws.com"

    }

  }


  rules {

    description = "Route /files to Azure bucket"

    enabled     = true

    expression  = "(http.request.uri.path wildcard \"*/files/*\")"

    provider    = "azure_storage"

    parameters {

      host = "mystorage.blob.core.windows.net"

    }

  }


  rules {

    description = "Route /images to R2 bucket"

    enabled     = true

    expression  = "(http.request.uri.path wildcard \"*/images/*\")"

    provider    = "cloudflare_r2"

    parameters {

      host = "mybucketcustomdomain.example.com"

    }

  }

}


```

## More resources

Refer to the [Terraform Cloudflare provider documentation ↗](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs) for more information on the `cloudflare_cloud_connector_rules` resource.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/cloud-connector/","name":"Cloud Connector"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/cloud-connector/create-terraform/","name":"Configure Cloud Connector rules using Terraform"}}]}
```

---

---
title: Cloud Connector examples
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/cloud-connector/examples/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cloud Connector examples

[Route /images to an S3 Bucket using TerraformRoute requests with a URI path starting with /images to a specific AWS S3 bucket with Cloud Connector using Terraform.](https://developers.cloudflare.com/rules/cloud-connector/examples/route-images-to-aws-s3-using-terraform/)[Route /images to an S3 BucketRoute requests with a URI path starting with /images to a specific AWS S3 bucket using Cloud Connector.](https://developers.cloudflare.com/rules/cloud-connector/examples/route-images-to-s3/)[Send EU visitors to a Google Cloud Storage bucketRoute all traffic from EU visitors to a Google Cloud Storage bucket using Cloud Connector.](https://developers.cloudflare.com/rules/cloud-connector/examples/send-eu-visitors-to-gcs/)[Serve /static-assets from Azure Blob StorageRoute requests with a URI path starting with /static-assets to an Azure Blob Storage container using Cloud Connector.](https://developers.cloudflare.com/rules/cloud-connector/examples/serve-static-assets-from-azure/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/cloud-connector/","name":"Cloud Connector"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/cloud-connector/examples/","name":"Cloud Connector examples"}}]}
```

---

---
title: Route /images to an S3 Bucket using Terraform
description: Route requests with a URI path starting with `/images` to a specific AWS S3 bucket with Cloud Connector using Terraform.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/cloud-connector/examples/route-images-to-aws-s3-using-terraform.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Route /images to an S3 Bucket using Terraform

Route requests with a URI path starting with `/images` to a specific AWS S3 bucket with Cloud Connector using Terraform.

Note

Terraform code snippets below refer to the v4 SDK only.

The following example defines a single Cloud Connector rule for a zone using Terraform. The rule routes requests to `/images` on your domain to an AWS S3 bucket.

```

resource "cloudflare_cloud_connector_rules" "serve_images_in_aws" {

  zone_id = "<ZONE_ID>"

  rules {

    description = "Route images to AWS S3 bucket"

    enabled     = true

    expression  = "http.request.full_uri wildcard \"https://<YOUR_HOSTNAME>/images/*\""

    provider    = "aws_s3"

    parameters {

      host = "<BUCKET_NAME>.s3.amazonaws.com"

    }

  }

}


```

## Additional resources

For additional guidance on using Terraform with Cloudflare, refer to the following resources:

* [Terraform documentation](https://developers.cloudflare.com/terraform/)
* [Cloudflare Provider for Terraform ↗](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs) (reference documentation)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/cloud-connector/","name":"Cloud Connector"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/cloud-connector/examples/","name":"Cloud Connector examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/cloud-connector/examples/route-images-to-aws-s3-using-terraform/","name":"Route /images to an S3 Bucket using Terraform"}}]}
```

---

---
title: Route /images to an S3 Bucket
description: Route requests with a URI path starting with `/images` to a specific AWS S3 bucket using Cloud Connector.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/cloud-connector/examples/route-images-to-s3.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Route /images to an S3 Bucket

Route requests with a URI path starting with `/images` to a specific AWS S3 bucket using Cloud Connector.

To route requests to `/images` on your domain to an AWS S3 bucket:

1. In the Cloudflare dashboard, go to the **Cloud Connector** page.  
[ Go to **Cloud Connector** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/cloud-connector)
2. Select **Amazon S3** as your [cloud provider](https://developers.cloudflare.com/rules/cloud-connector/providers/).
3. Enter the bucket URL. You can structure the URL in two ways:  
   * **Subdomain-style URL**: Set the hostname to `<BUCKET_NAME>.s3.amazonaws.com`. In this case, your files should be organized in the root of the bucket, meaning the URI path will map directly to the file. For example, `https://<YOUR_HOSTNAME>/images/file.jpg` will map to `https://<BUCKET_NAME>.s3.amazonaws.com/images/file.jpg`.  
   * **URI path-style URL**: Set the hostname to `s3.amazonaws.com`. Here, your bucket must include a folder named `images`, and files should be placed inside this folder. The URI path will then include the bucket name, like `https://<YOUR_HOSTNAME>/<BUCKET_NAME>/images/file.jpg` mapping to `https://s3.amazonaws.com/<BUCKET_NAME>/images/file.jpg`.
4. (Optional) Use [URL Rewrite Rules](https://developers.cloudflare.com/rules/transform/url-rewrite/) to adjust the URL structure. For example, you can [create a URL rewrite](https://developers.cloudflare.com/rules/transform/url-rewrite/create-dashboard/) that changes `/images` to `/<BUCKET_NAME>/images` to match the URI path-style URL structure.
5. (Optional) Use [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/) to adjust the caching behavior for objects returned from the bucket. For example, you can [create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) that caches every returned object matching the `/images/*` URI path for seven days:  
   * **If incoming requests match** \> Custom filter expression: `(starts_with(http.request.uri.path, "/images/"))`  
   * **Cache eligibility**: Eligible for cache  
         * **Edge TTL** \> Ignore cache-control header and use this TTL: _7 days_
6. Select **Next** and enter a descriptive name like `Route images to S3` in **Cloud Connector name**.
7. Under **If**, select **Custom filter expression** and enter the following expression:  
`http.request.full_uri wildcard "http*://<YOUR_HOSTNAME>/images/*"`  
Replace `<YOUR_HOSTNAME>` with desired hostname.
8. Select **Deploy** to activate the rule.

This setup will route all traffic matching `http*://<YOUR_HOSTNAME>/images/*` (HTTPS and HTTP requests) to your S3 bucket. Make sure to replace `<YOUR_HOSTNAME>` with your actual hostname and adjust the example paths according to your setup.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/cloud-connector/","name":"Cloud Connector"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/cloud-connector/examples/","name":"Cloud Connector examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/cloud-connector/examples/route-images-to-s3/","name":"Route /images to an S3 Bucket"}}]}
```

---

---
title: Send EU visitors to a Google Cloud Storage bucket
description: Route all traffic from EU visitors to a Google Cloud Storage bucket using Cloud Connector.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/cloud-connector/examples/send-eu-visitors-to-gcs.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Send EU visitors to a Google Cloud Storage bucket

Route all traffic from EU visitors to a Google Cloud Storage bucket using Cloud Connector.

To route requests from visitors in the European Union to a Google Cloud Storage bucket:

1. In the Cloudflare dashboard, go to the **Cloud Connector** page.  
[ Go to **Cloud Connector** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/cloud-connector)
2. Select **Google Cloud Storage** as your [cloud provider](https://developers.cloudflare.com/rules/cloud-connector/providers/).
3. Enter the bucket URL. You can structure the URL in two ways:  
   * **Subdomain-style URL**: For `<BUCKET_NAME>.storage.googleapis.com`, your files should be organized in the root of the bucket. For example, `https://<YOUR_HOSTNAME>/index.html` will map to `https://<BUCKET_NAME>.storage.googleapis.com/index.html`.  
   * **URI path-style URL**: If you set the hostname to `storage.googleapis.com`, your bucket must include folders corresponding to the intended URI paths. For example, if you want `https://<YOUR_HOSTNAME>/eu/index.html` to map to a file in your bucket, the file should be placed at `https://storage.googleapis.com/<BUCKET_NAME>/eu/index.html`.
4. (Optional) Use [URL Rewrite Rules](https://developers.cloudflare.com/rules/transform/url-rewrite/) to adjust the URL structure. For example, you can [create a URL rewrite](https://developers.cloudflare.com/rules/transform/url-rewrite/create-dashboard/) that changes `/eu` to `/<BUCKET_NAME>` to match the URI path-style URL structure.
5. (Optional) Use [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/) to adjust the caching behavior for objects returned from the bucket. For example, you can [create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) that caches every returned object matching the `/eu` URI path for seven days (defined through the **Edge TTL** setting).
6. Select **Next** and enter a descriptive name like `Route EU visitors to GCP` in **Cloud Connector name**.
7. Under **If**, select **Custom filter expression** and enter the following expression:`(ip.src.is_in_european_union)`  
This expression targets traffic from European Union users.
8. Select **Deploy** to activate the rule.

This configuration will route traffic from EU visitors to your Google Cloud Storage bucket. Make sure to replace `<YOUR_HOSTNAME>` with your actual hostname and adjust the example paths according to your setup.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/cloud-connector/","name":"Cloud Connector"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/cloud-connector/examples/","name":"Cloud Connector examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/cloud-connector/examples/send-eu-visitors-to-gcs/","name":"Send EU visitors to a Google Cloud Storage bucket"}}]}
```

---

---
title: Serve /static-assets from Azure Blob Storage
description: Route requests with a URI path starting with `/static-assets` to an Azure Blob Storage container using Cloud Connector.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/cloud-connector/examples/serve-static-assets-from-azure.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Serve /static-assets from Azure Blob Storage

Route requests with a URI path starting with `/static-assets` to an Azure Blob Storage container using Cloud Connector.

To serve static assets from an Azure Blob Storage container:

1. In the Cloudflare dashboard, go to the **Cloud Connector** page.  
[ Go to **Cloud Connector** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/cloud-connector)
2. Select **Microsoft Azure** as your [cloud provider](https://developers.cloudflare.com/rules/cloud-connector/providers/).
3. Enter the bucket URL. Use the following URL structure:  
   * **Subdomain-style URL**: Set the hostname to `<BUCKET_NAME>.blob.core.windows.net`. In this case, your bucket should include a folder named `static-assets`, and files should be placed inside this folder. For example, `https://<YOUR_HOSTNAME>/static-assets/style.css` will map to `https://<BUCKET_NAME>.blob.core.windows.net/static-assets/style.css`.
4. (Optional) Use [URL Rewrite Rules](https://developers.cloudflare.com/rules/transform/url-rewrite/) to adjust the URL structure. For example, you can [create a URL rewrite](https://developers.cloudflare.com/rules/transform/url-rewrite/create-dashboard/) that changes `/static-assets` to `/my-pages-project/static-assets` to match the file structure of your object storage bucket.
5. (Optional) Use [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/) to adjust the caching behavior for objects returned from the bucket. For example, you can [create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) that caches every returned object matching the `/static-assets` URI path for seven days (defined through the **Edge TTL** setting).
6. Click **Next** and enter a descriptive name like `Serve static assets from Azure` in **Cloud Connector name**.
7. Under **If**, select **Custom filter expression** and enter the following expression:`http.request.full_uri wildcard "http*://<YOUR_HOSTNAME>/static-assets/*"`
8. Select **Deploy** to activate the rule.

This setup ensures that all traffic matching `http*://<YOUR_HOSTNAME>/static-assets/*` (HTTPS and HTTP requests) is served from your Azure Blob Storage container. Make sure to replace `<YOUR_HOSTNAME>` with your actual hostname and adjust the example paths according to your setup.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/cloud-connector/","name":"Cloud Connector"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/cloud-connector/examples/","name":"Cloud Connector examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/cloud-connector/examples/serve-static-assets-from-azure/","name":"Serve /static-assets from Azure Blob Storage"}}]}
```

---

---
title: Supported cloud providers in Cloud Connector
description: Cloud Connector currently supports the following cloud providers and services:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/cloud-connector/providers.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Supported cloud providers in Cloud Connector

Cloud Connector currently supports the following cloud providers and services:

* Cloudflare R2
* Amazon Web Services - S3
* Google Cloud Platform - Cloud Storage
* Microsoft Azure - Blob Storage

## Cloudflare R2

The Cloudflare R2 bucket must be public and [exposed using a custom domain](https://developers.cloudflare.com/r2/buckets/public-buckets/). Buckets exposed using an `r2.dev` subdomain are not supported.

Additionally, the custom domain must be defined in the same zone where you are configuring the Cloud Connector rule.

## Amazon Web Services - S3

The hostname of your S3 bucket URL must have one of the following formats (where `*` is a wildcard character):

* `*s3.amazonaws.com`
* `*s3.<REGION>.amazonaws.com`
* `*s3-website.<REGION>.amazonaws.com`
* `*s3-website-<REGION>.amazonaws.com`

Cloud Connector supports both subdomain and URI path-style URLs:

* **Subdomain-style URLs**: Set the hostname to `<BUCKET_NAME>.s3.amazonaws.com`. In this case, your files are accessible directly under the root of the bucket. For example, `https://example.com/index.html` will map to `https://<BUCKET_NAME>.s3.amazonaws.com/index.html`. When using **Full (Strict)** SSL/TLS mode, the `<BUCKET_NAME>` cannot include dots (use dashes instead). Refer to [SSL connections to AWS S3 endpoints](#ssl-connections-to-aws-s3-endpoints) for details.
* **URI path-style URLs**: Set the hostname to `s3.amazonaws.com`. Here, your bucket name must be part of the URI path in your requests. For example, if your bucket name is `<BUCKET_NAME>`, files will be available on paths like `https://example.com/<BUCKET_NAME>/index.html`, and your Cloud Connector rule should filter traffic based on the URI path starting with `/<BUCKET_NAME>`.

### SSL connections to AWS S3 endpoints

The SSL setting applied to requests between Cloud Connector and AWS S3 depends on the type of S3 endpoint you use:

* **HTTPS-supported endpoints**: For hostnames like `*s3.<REGION>.amazonaws.com` and `*s3.amazonaws.com`, Cloudflare will connect to AWS S3 over HTTPS if you set your zone's SSL/TLS mode to **Full** or **Full (Strict)**. When using **Full (Strict)**, the bucket name cannot include dots (use dashes instead).
* **Non-HTTPS endpoints**: For website-style hostnames such as `*s3-website.<REGION>.amazonaws.com` or `*s3-website-<REGION>.amazonaws.com`, which do not support HTTPS, Cloudflare will default to **Flexible SSL**.

### Get the bucket URL

1. Go to the [Amazon S3 console ↗](https://console.aws.amazon.com/s3/) and select **Buckets** in the navigation pane.
2. Select the bucket name.
3. Go to the **Properties** tab.
4. Select the **Static Website Hosting** card. The **Endpoint** field shows your bucket URL.

For more information, refer to the [Amazon S3 documentation ↗](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EnableWebsiteHosting.html).

Once you configure Cloud Connector with your storage provider's public bucket, you may wish that only Cloudflare can access the objects in that bucket. To achieve this, check your provider's documentation on how to create a policy that only allows incoming requests from [Cloudflare IP addresses ↗](https://www.cloudflare.com/ips/).

## Google Cloud Platform - Cloud Storage

The hostname of your Cloud Storage bucket URL must be the following (where `*` is a wildcard character):

* `*storage.googleapis.com`
* `*storage.cloud.google.com`

Cloud Connector supports both subdomain and URI path-style URLs:

* **Subdomain-style URLs**: Set the hostname to `<BUCKET_NAME>.storage.googleapis.com`. In this case, your files are accessible directly under the root of the bucket. For example, `https://example.com/index.html` will map to `https://<BUCKET_NAME>.storage.googleapis.com/index.html`.
* **URI path-style URLs**: Set the hostname to `storage.googleapis.com`. Here, your bucket name must be part of the URI path in your requests. For example, if your bucket name is `<BUCKET_NAME>`, files will be available on paths like `https://example.com/<BUCKET_NAME>/index.html`, and your Cloud Connector rule should filter traffic based on the URI path starting with `/<BUCKET_NAME>`.

### Get the bucket URL

1. Go to the [Google Cloud console ↗](https://console.cloud.google.com/storage/browser) and select **Buckets**.
2. Select the bucket name.
3. For one of the files already in the bucket, select the link icon in the **Public** column to copy the file's public URL to the clipboard. The file URL will have the following format:  
`https://storage.googleapis.com/<BUCKET_NAME>/<OBJECT_NAME>`  
To obtain the subdomain bucket URL, refactor the file URL to `<BUCKET_NAME>.storage.googleapis.com` format.  
To obtain the URI path bucket URL, remove `https://` and `/<BUCKET_NAME>/<OBJECT_NAME>` from the file URL.

If the files in your bucket are not publicly accessible, you must change the bucket permissions. For details, refer to the [Google Cloud Storage documentation ↗](https://cloud.google.com/storage/docs/access-control/making-data-public#buckets).

Once you configure Cloud Connector with your storage provider's public bucket, you may wish that only Cloudflare can access the objects in that bucket. To achieve this, check your provider's documentation on how to create a policy that only allows incoming requests from [Cloudflare IP addresses ↗](https://www.cloudflare.com/ips/).

## Microsoft Azure - Blob Storage

The hostname of your Blob Storage bucket URL must have one of the following formats:

* `<BUCKET_NAME>.blob.core.windows.net`
* `<BUCKET_NAME>.web.core.windows.net`

For Azure Blog Storage, Cloud Connector supports only subdomain URLs like `<BUCKET_NAME>.blob.core.windows.net`. This means that your files will be accessible directly under the root of the bucket. For example, `https://example.com/index.html` will map to `https://<BUCKET_NAME>.blob.core.windows.net/index.html`.

### Get the bucket URL

1. Go to the [Azure portal ↗](https://portal.azure.com/) and select your storage account.
2. In the menu pane, under **Settings**, select **Endpoints**.
3. Get your bucket URL from the **Blob service** endpoint or the **Static website** endpoint.

If the blob container is not configured for public access, you must change the container settings. For details, refer to the [Azure Storage documentation ↗](https://learn.microsoft.com/en-us/azure/storage/blobs/anonymous-read-access-configure?tabs=portal).

Once you configure Cloud Connector with your storage provider's public bucket, you may wish that only Cloudflare can access the objects in that bucket. To achieve this, check your provider's documentation on how to create a policy that only allows incoming requests from [Cloudflare IP addresses ↗](https://www.cloudflare.com/ips/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/cloud-connector/","name":"Cloud Connector"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/cloud-connector/providers/","name":"Supported cloud providers in Cloud Connector"}}]}
```

---

---
title: Custom Errors
description: Use Custom Errors to return custom content to your website visitors in case of HTTP errors returned by an origin server or by a Cloudflare product (including Cloudflare Workers), or when showing a security challenge.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/custom-errors/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Custom Errors

Use Custom Errors to return custom content to your website visitors in case of HTTP errors returned by an origin server or by a Cloudflare product (including [Cloudflare Workers](https://developers.cloudflare.com/workers/)), or when showing a [security challenge](https://developers.cloudflare.com/cloudflare-challenges/).

You can configure custom error content using the following methods:

* [**Error Page**](#error-pages): An HTML page shown to website visitors when a specific error occurs (refer to the different [error page types](https://developers.cloudflare.com/rules/custom-errors/reference/error-page-types/)) or when showing a security challenge. Error Pages can be defined at the zone level and at the account level on paid plans, with zone-level configurations taking precedence.
* [**Custom Error Rule**](#custom-error-rules): Defines the conditions under which Cloudflare will serve a custom error response to visitors in case of HTTP errors (status codes `400` and above), and the exact content that will be served. A matching custom error rule has priority over an Error Page configured at the account or at the zone level that would apply to the same error.

Custom Errors require that you [proxy the DNS records](https://developers.cloudflare.com/dns/proxy-status/) of your domain (or subdomain) through Cloudflare.

## How it works

Cloudflare has a set of default pages for presenting errors and challenges to your website visitors. You can customize those pages using Error Pages and Custom Error Rules.

When an error of a [specific type](https://developers.cloudflare.com/rules/custom-errors/reference/error-page-types/) occurs, Cloudflare does the following:

1. Search for a configured Error Page at the account level for the specific error.
2. Search for a configured Error Page at the zone level for the specific error (it will have priority over the account-level Error Page, if any).
3. Search for a matching custom error rule at the account level. The rule will have priority over 500 and 1000 class Error Pages at the account or zone level.
4. Search for a matching custom error rule at the zone level. The rule will have priority over 500 and 1000 class Error Pages at the account or zone level and over custom error rules at the account level.
5. If a security rule like a [WAF custom rule](https://developers.cloudflare.com/waf/custom-rules/) or a [rate limiting rule](https://developers.cloudflare.com/waf/rate-limiting-rules/) triggers a custom block response instead of a default Cloudflare WAF block page, the rule-specific block response will have priority over Error Pages or a matching custom error rule.
6. If any of the previous configurations apply, serve the custom error content to the visitor. If not, serve the default error page for the specific error type.

Note

To customize a challenge page or a block page, use an Error Page, since Custom Error Rules will not be applied to security actions originating from Cloudflare products. Keep in mind that [custom WAF response](https://developers.cloudflare.com/waf/custom-rules/create-dashboard/#configure-a-custom-response-for-blocked-requests) takes precedence over an Error Page and custom error rules.

## Availability

Custom Errors are available to all paid plans. The exact features depend on your Cloudflare plan.

| Free               | Pro | Business | Enterprise |     |
| ------------------ | --- | -------- | ---------- | --- |
| Availability       | No  | Yes      | Yes        | Yes |
| Number of rules    | 0   | 25       | 50         | 300 |
| Number of assets   | 0   | 25       | 50         | 300 |
| Error Pages        | No  | Yes      | Yes        | Yes |
| Origin Error Pages | No  | No       | No         | Yes |

---

## Error Pages

Cloudflare uses a wide range of [error codes](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/) to identify issues in handling request traffic. By default, these error pages mention Cloudflare; however, you can create custom error pages to provide a consistent brand experience for your users.

Error Pages do not apply to responses with an HTTP status code of `500`, `501`, `503`, or `505`. These exceptions help avoid issues with specific API endpoints and other web applications. You can still customize responses for these status codes using Custom Error Rules.

If you are on a Cloudflare paid plan, you can create custom error pages at the zone level or for your entire account. Zone-level error pages have priority over account-level error pages.

Additionally, Enterprise customers can customize 5XX error pages (except errors `520`\-`527`) at their origin by turning on **Origin Error Pages** in **Error Pages** in the dashboard.

You can design custom error pages to appear during a security challenge or when an error occurs. For more information on the different error page types, refer to [Error page types](https://developers.cloudflare.com/rules/custom-errors/reference/error-page-types/).

Note

Cloudflare will return the default Cloudflare error page instead of your custom Error Pages if the incoming request does not contain an `accept-encoding` header. This does not apply to responses originating from Custom Error Rules.

## Custom Error Rules

A custom error rule defines the conditions under which Cloudflare will serve custom error content to visitors in case of HTTP errors (status codes `400` and above), and the exact content that will be served to visitors.

When defining the content to serve, you provide either an inline response or the URL of an existing webpage. The URL can point to a webpage or to a different resource such as JSON content.

When you provide a URL, Cloudflare will gather any required images, CSS, and JavaScript code and save a minified version of the full page in the Cloudflare global network. This resource is called a [custom error asset](#custom-error-assets), which you can use in one or more custom error rules in the same scope of the asset (zone or account).

When a custom error rule is triggered, Cloudflare will replace the body with the response you previously defined and (optionally) the response HTTP status code sent to the visitor. Cloudflare will keep any existing HTTP response headers except for `Content-Type` and `Content-Length`.

Additionally, you can configure [Response Header Transform Rules](https://developers.cloudflare.com/rules/transform/response-header-modification/) for error responses to add, change, or remove HTTP headers from the response.

Custom error rules have priority over [Error Pages](#error-pages).

## Custom Error Assets

A custom error asset corresponds to a web resource such as an HTML web page (including any referenced images, CSS, and JavaScript code) that Cloudflare fetches and saves based on a URL you provide, to be served to visitors as an error page.

Once the custom error asset is stored in Cloudflare's global network, the URL you initially provided no longer needs to be available. You can update an existing custom error asset by fetching it again. The metadata associated with each custom error asset includes the timestamp when the last fetch occurred, and this information is displayed in the dashboard.

You can use a custom error asset in one or more [custom error rules](#custom-error-rules) in the same scope where you defined the asset (zone or account).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/custom-errors/","name":"Custom Errors"}}]}
```

---

---
title: Common API calls for Custom Errors
description: The following sections provide examples of common API calls for managing custom error assets and Error Pages at the zone level.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/custom-errors/api-calls.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Common API calls for Custom Errors

The following sections provide examples of common API calls for managing custom error assets and Error Pages at the zone level.

To perform the same operations at the account level, use the corresponding account-level API endpoints.

### Create a custom error asset

The following `POST` request creates a new custom error asset in a zone based on the provided URL:

Terminal window

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_pages/assets" \

--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

--json '{

  "name": "500_error_template",

  "description": "Standard 5xx error template page",

  "url": "https://example.com/errors/500_template.html"

}'


```

```

{

  "result": {

    "name": "500_error_template",

    "description": "Standard 5xx error template page",

    "url": "https://example.com/errors/500_template.html",

    "last_updated": "2025-02-10T11:36:07.810215Z",

    "size_bytes": 2048

  },

  "success": true

}


```

To create an asset at the account level, use the account-level endpoint:

```

https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/custom_pages/assets


```

### List custom error assets

The following `GET` request retrieves a list of custom error assets configured in the zone:

Terminal window

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_pages/assets" \

--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"


```

```

{

  "result": [

    {

      "name": "500_error_template",

      "description": "Standard 5xx error template page",

      "url": "https://example.com/errors/500_template.html",

      "last_updated": "2025-02-10T11:36:07.810215Z",

      "size_bytes": 2048

    }

    // ...

  ],

  "success": true,

  "errors": [],

  "messages": [],

  "result_info": {

    "count": 2,

    "page": 1,

    "per_page": 20,

    "total_count": 2,

    "total_pages": 1

  }

}


```

To retrieve a list of assets at the account level, use the account-level endpoint:

```

https://api.cloudflare.com/client/v4/accounts/$ZONE_ID/custom_pages/assets


```

### Update a custom error asset

The following `PUT` request updates the URL of an existing custom error asset at the zone level named `500_error_template`:

Terminal window

```

curl --request PUT \

"https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_pages/assets/500_error_template" \

--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

--json '{

  "description": "Standard 5xx error template page",

  "url": "https://example.com/errors/500_new_template.html"

}'


```

```

{

  "result": {

    "name": "500_error_template",

    "description": "Standard 5xx error template page",

    "url": "https://example.com/errors/500_new_template.html",

    "last_updated": "2025-02-10T13:13:07.810215Z",

    "size_bytes": 3145

  },

  "success": true

}


```

You can update the asset description and URL. You cannot update the asset name after creation.

If you provide the same URL when updating an asset, Cloudflare will fetch the URL again, along with its resources.

To update an asset at the account level, use the account-level endpoint:

```

https://api.cloudflare.com/client/v4/accounts/{account_id}/custom_pages/assets/{asset_name}


```

### Get a custom error asset

The following `GET` request retrieves the details of an existing custom error asset at the zone level named `500_error_template`:

Terminal window

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_pages/assets/500_error_template" \

--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"


```

```

{

  "result": {

    "name": "500_error_template",

    "description": "Standard 5xx error template page",

    "url": "https://example.com/errors/500_new_template.html",

    "last_updated": "2025-02-10T13:13:07.810215Z",

    "size_bytes": 3145

  },

  "success": true

}


```

To retrieve an asset at the account level, use the account-level endpoint:

```

https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/custom_pages/assets/$ASSET_NAME


```

### Delete a custom error asset

The following `DELETE` request deletes an existing custom error asset at the zone level named `500_error_template`:

Terminal window

```

curl --request DELETE \

"https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_pages/assets/500_error_template" \

--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN"


```

If the request is successful, the response will have a `204` HTTP status code.

To delete an asset at the account level, use the account-level endpoint:

```

https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/custom_pages/assets/$ASSET_NAME


```

### Get error page

This example obtains the current configuration for the `Rate limiting block` error page (with ID `ratelimit_block`).

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Custom Pages Write`
* `Custom Pages Read`
* `Zone Settings Write`
* `Zone Settings Read`

Get a custom page

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_IDENTIFIER/custom_pages/ratelimit_block" \

  --request GET \

  --header "X-Auth-Email: $CLOUDFLARE_EMAIL" \

  --header "X-Auth-Key: $CLOUDFLARE_API_KEY"


```

```

{

  "result": {

    "id": "ratelimit_block",

    "description": "Rate limit Block",

    "required_tokens": [],

    "preview_target": "block:rate-limit",

    "created_on": "2025-06-03T08:33:17.091587Z",

    "modified_on": "2025-06-03T08:33:17.091587Z",

    "url": null,

    "state": "default"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

The response indicates that the page is currently set to the Cloudflare default page (`"state": "default"`).

For a list of error page identifiers, refer to [Error page types](https://developers.cloudflare.com/rules/custom-errors/reference/error-page-types/).

### Update error page

This example defines a custom error page for `Rate limiting block` errors (with ID `ratelimit_block`) based on the provided URL.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Custom Pages Write`
* `Zone Settings Write`

Update a custom page

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_IDENTIFIER/custom_pages/ratelimit_block" \

  --request PUT \

  --header "X-Auth-Email: $CLOUDFLARE_EMAIL" \

  --header "X-Auth-Key: $CLOUDFLARE_API_KEY" \

  --json '{

    "state": "customized",

    "url": "https://example.com/rate_limiting_block_error_page.html"

  }'


```

```

{

  "result": {

    "id": "ratelimit_block",

    "description": "Rate limit Block",

    "required_tokens": [],

    "preview_target": "block:rate-limit",

    "created_on": "2025-06-03T08:33:17.091587Z",

    "modified_on": "2025-06-03T08:35:32.639114Z",

    "url": "https://example.com/rate_limiting_block_error_page.html",

    "state": "customized"

  },

  "success": true,

  "errors": [],

  "messages": []

}


```

To set the error page back to the default page, use `"state": "default"` in the request body.

For a list of error page identifiers, refer to [Error page types](https://developers.cloudflare.com/rules/custom-errors/reference/error-page-types/).

## More resources

* [Custom Error Pages API reference](https://developers.cloudflare.com/api/resources/custom%5Fpages/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/custom-errors/","name":"Custom Errors"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/custom-errors/api-calls/","name":"Common API calls for Custom Errors"}}]}
```

---

---
title: Create custom error rules
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/custom-errors/create-rules.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create custom error rules

## In the dashboard

### Create a custom error rule

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Create rule** \> **Custom Error Rule**.
3. Enter a descriptive name for the rule in **Rule name**.
4. Under **If incoming requests match**, select one of the following options:  
   * **Custom filter expression**: The rule will only apply to traffic matching a custom expression. Define the [rule expression](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/) to configure which requests should be rewritten. Use either the Expression Builder or the Expression Editor to define the custom expression. For more information, refer to [Edit expressions in the dashboard](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/).  
   * **All incoming requests**: The rule will apply to all responses with a `400` status code or above, except for block and challenge actions issued by Cloudflare’s security products.
5. In **Deliver a custom error response**, select the response type (either _Custom error asset_ or one of the available inline responses).  
If you select _Custom error asset_, select an existing custom error asset in **Asset**, or select **Create new asset** to [create a new custom error asset](#create-a-custom-error-asset-dashboard).  
If you select _JSON response_, _HTML response_, _Text response_, or _XML response_, enter the custom error response you want to send to web site visitors in **JSON response**, **HTML response**, **Text response**, or **XML response**, respectively. The response can include [error tokens](https://developers.cloudflare.com/rules/custom-errors/reference/error-tokens/) that Cloudflare will replace with real values before sending the response to the visitor. The maximum response size is 10 KB.
6. (Optional) In **Response code**, enter the HTTP status code of the response (an integer value between `400` and `999`). If provided, this value will override the current response status code.
7. (Optional) Under **Place at**, define where to place the rule in the rules list: first rule in the list, last rule in the list, or in a custom position (after a given rule).
8. To save and deploy your rule, select **Deploy**. If you are not ready to deploy your rule, select **Save as Draft**.

### Create a custom error asset

1. In the **Create Custom Error Asset** sidebar, enter a name for the asset in **Asset name**.
2. (Optional) Enter a description for the asset in **Description**.
3. In **URL**, enter the URL of the page you want to fetch and store in Cloudflare's global network. Cloudflare will fetch all the page resources and store a minified version of the page you can use in one or more custom error rules.
4. Select **Save**.

To review existing custom error assets, go to **Rules** \> **Settings** \> **Custom Error Assets** tab.

## Via API

To configure a custom error rule via API:

1. (Optional) [Create a custom error asset](#create-a-custom-error-asset-api) based on a URL you provide.
2. [Create a custom error rule](#create-a-custom-error-rule-api) in the `http_custom_errors` phase, using the [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/).

### Create a custom error asset

The following `POST` request creates new a custom error asset in a zone based on the provided URL:

Terminal window

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_pages/assets" \

--header "Authorization: Bearer <API_TOKEN>" \

--json '{

  "name": "500_error_template",

  "description": "Standard 5xx error template page",

  "url": "https://example.com/errors/500_template.html"

}'


```

```

{

  "result": {

    "name": "500_error_template",

    "description": "Standard 5xx error template page",

    "url": "https://example.com/errors/500_template.html",

    "last_updated": "2025-02-10T11:36:07.810215Z",

    "size_bytes": 2048

  },

  "success": true

}


```

### Create a custom error rule

When creating a custom error rule via API, make sure you:

* Set the rule action to `serve_error`.
* Define the [rule parameters](https://developers.cloudflare.com/rules/custom-errors/reference/parameters/#custom-error-rules) in the `action_parameters` field according to response type.
* Deploy the rule to the `http_custom_errors` phase.

The first rule in the `http_custom_errors` phase ruleset that matches will be applied. No other rules in the ruleset will be matched or applied. Additionally, custom error rules defined at the zone level will have priority over rules defined at the account level.

#### General procedure

Follow this workflow to create a custom error rule for a given zone via API:

1. Use the [List zone rulesets](https://developers.cloudflare.com/api/resources/rulesets/methods/list/) operation to check if there is already a ruleset for the `http_custom_errors` phase at the zone level.
2. If the phase ruleset does not exist, create it using the [Update a zone entry point ruleset](https://developers.cloudflare.com/api/resources/rulesets/subresources/phases/methods/update/) operation, which allows you to create a ruleset if it does not exist and update all the rules in the ruleset. Create the ruleset in the `http_custom_errors` phase.  
If the phase ruleset already exists, use the [Update a zone entry point ruleset](https://developers.cloudflare.com/api/resources/rulesets/subresources/phases/methods/update/) operation to replace all the rules in the ruleset, or the [Add a rule to a ruleset](https://developers.cloudflare.com/ruleset-engine/rulesets-api/add-rule/) operation to add a rule to the existing rules in the ruleset.

To create a custom error rule at the account level, use the corresponding account-level API endpoints.

#### Example

This example configures a custom error rule returning a [previously created custom error asset](#create-a-custom-error-asset-api) named `500_error_template` for responses with a `500` HTTP status code.

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone entry point ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_custom_errors/entrypoint" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "serve_500_template",

            "action": "serve_error",

            "action_parameters": {

                "asset_name": "500_error_template",

                "content_type": "text/html"

            },

            "expression": "http.response.code eq 500",

            "enabled": true

        }

    ]

  }'


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

This `PUT` request, corresponding to the [Update a zone entry point ruleset](https://developers.cloudflare.com/api/resources/rulesets/subresources/phases/methods/update/) operation, replaces any existing rules in the `http_custom_errors` phase entry point ruleset.

### Required API token permissions

The API token used in API requests to manage Custom Error Rules and Custom Error Assets must have at least the following permission:

* _Custom Error Rules_ \> _Edit_

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/custom-errors/","name":"Custom Errors"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/custom-errors/create-rules/","name":"Create custom error rules"}}]}
```

---

---
title: Edit Error Pages
description: You can define custom Error Pages for the following errors and challenges:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/custom-errors/edit-error-pages.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Edit Error Pages

You can define custom [Error Pages](https://developers.cloudflare.com/rules/custom-errors/#error-pages) for the following errors and challenges:

* WAF block
* IP/Country block
* IP/Country challenge
* 500 class errors
* 1000 class errors
* Managed challenge / I'm Under Attack Mode
* Rate limiting block

For more information on the different types of Error Pages, refer to [Error page types](https://developers.cloudflare.com/rules/custom-errors/reference/error-page-types/).

To return custom error responses for requests that match specific conditions, use [Custom Error Rules](https://developers.cloudflare.com/rules/custom-errors/#custom-error-rules) instead.

## 1\. Design your custom error page

Before defining a custom error page in your Cloudflare account, you will need to design and code that page. It can be hosted on your own web server or using a Cloudflare product like [Snippets](https://developers.cloudflare.com/rules/snippets/).

When designing your custom error page, you can include page-specific [custom error tokens](https://developers.cloudflare.com/rules/custom-errors/reference/error-tokens/). Each custom error token provides diagnostic information that appears on the error page.

To display a custom page for each error, create a separate page per error. For example, to create a custom error page for both **IP/Country Block** and **WAF block**, you must design and publish two separate pages.

Notes

* Your custom error page should include a page-specific custom error token if applicable and cannot exceed 1.5 MB (1,500,000 bytes). Also, it must include HTML `<head>` and `</head>` tags.
* Make sure that the `referrer` meta tag is not present in your custom error page's HTML code since it will disrupt [Cloudflare challenges](https://developers.cloudflare.com/cloudflare-challenges/): `<meta name="referrer" (...) />`

You can use the following template to start building your error page:

```

<html>

  <head></head>

  <body>

    ::[REPLACE WITH CUSTOM ERROR TOKEN NAME]::

  </body>

</html>


```

Example error page for 5XX errors

The following HTML code is an example error page for 5XX errors without styling:

```

<!doctype html>

<html>

  <head>

    <meta charset="utf-8" />

    <title>5XX Level Errors page</title>

  </head>

  <body>

    <h1>5XX Level Errors</h1>

    <h2>::CLOUDFLARE_ERROR_500S_BOX::</h2>

  </body>

</html>


```

---

## 2\. Update an error page in the dashboard

You can define an error page at the zone level or for your entire account. Zone-level error pages have priority over account-level error pages.

* [ Zone level ](#tab-panel-5995)
* [ Account level ](#tab-panel-5996)

To edit a zone-level custom error page:

1. In the Cloudflare dashboard, go to the **Error Pages** page.  
[ Go to **Error Pages** ](https://dash.cloudflare.com/?to=/:account/:zone/error-pages)
2. Identify your desired custom error page type.
3. (Optional) To preview the current error page (default or custom), select the link in the **Show** column.
4. To edit the error page, select the three dots > **Edit** next to the page type you previously identified.
5. To use Cloudflare's default page, select **Cloudflare default page.** To provide a custom error page, select **Custom page** and enter the URL of the custom error page you created.
6. Select **Confirm**.

To update an account-level custom error page:

1. In the Cloudflare dashboard, go to the **Settings** page.  
[ Go to **Configurations** ](https://dash.cloudflare.com/?to=/:account/configurations)
2. Go to **Error Pages** and identify your desired custom error page type.
3. (Optional) To preview the current error page (default or custom), select the link in the **Show** column.
4. To edit the error page, select the three dots > **Edit** next to the page type you previously identified.
5. To use Cloudflare's default page, select **Cloudflare default page.** To provide a custom error page, select **Custom page** and enter the URL of the custom error page you created.
6. Select **Confirm**.

## Fetch custom error page again

After successfully setting the content of the custom error page in **Error Pages**, you can remove the page from your origin server.

If in the future, you need to update your custom error page, you must fetch the page again, even if the page URL remains unchanged. In this case, next to the page type you want to update, select the three dots > **Fetch custom page again**.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/custom-errors/","name":"Custom Errors"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/custom-errors/edit-error-pages/","name":"Edit Error Pages"}}]}
```

---

---
title: Example custom error rules
description: The provided examples use the following fields in their rule expressions:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/custom-errors/example-rules.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Example custom error rules

The provided examples use the following fields in their rule expressions:

* [http.response.code](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.response.code/) (Response Status Code): Represents the HTTP status code returned to the client, either set by a Cloudflare product or returned by the origin server. Use this field to customize the response for error codes returned by the origin server or by a Cloudflare product such as a Worker.
* [cf.response.1xxx\_code](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.response.1xxx%5Fcode/): Contains the specific error code for Cloudflare-generated errors. This field will only work for Cloudflare-generated errors such as [52X](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/) and [1XXX](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/).

### Custom JSON response for all 5XX errors

This example configures a custom JSON error response for all 5XX errors (`500`\-`599`) in a zone. The HTTP status code of the custom error response will be set to `530`.

* [ Dashboard ](#tab-panel-5997)
* [ API ](#tab-panel-5998)

**Custom error rule configuration:**

* **Name**: `Custom JSON response for all 5XX errors`
* **If incoming requests match** \> **Custom filter expression**:  
| Field                | Operator                 | Value | Logic |  
| -------------------- | ------------------------ | ----- | ----- |  
| Response Status Code | greater than or equal to | 500   | And   |  
| Response Status Code | less than or equal to    | 599   |       |  
If using the Expression Editor:  
`(http.response.code ge 500 and http.response.code le 599)`
* **Response type**: _JSON response_
* **Response code**: `530`
* **JSON response**: `{"message": "A server error occurred."}`

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone entry point ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_custom_errors/entrypoint" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "json_response_for_5xx_errors",

            "action": "serve_error",

            "action_parameters": {

                "content": "{\"message\": \"A server error occurred.\"}",

                "content_type": "application/json",

                "status_code": 530

            },

            "expression": "http.response.code ge 500 and http.response.code lt 600",

            "enabled": true

        }

    ]

  }'


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

This `PUT` request, corresponding to the [Update a zone entry point ruleset](https://developers.cloudflare.com/api/resources/rulesets/subresources/phases/methods/update/) operation, replaces any existing rules in the `http_custom_errors` phase entry point ruleset.

### Custom HTML response with updated status code

This example configures a custom HTML error response for responses with a `500` HTTP status code, and redefines the response status code to `503`.

* [ Dashboard ](#tab-panel-5999)
* [ API ](#tab-panel-6000)

**Custom error rule configuration:**

* **Name**: `Custom HTML response for 500 errors`
* **If incoming requests match** \> **Custom filter expression**:  
| Field                | Operator | Value |  
| -------------------- | -------- | ----- |  
| Response Status Code | equal to | 500   |  
If using the Expression Editor:  
`(http.response.code eq 500)`
* **Response type**: _HTML response_
* **Response code**: `503`
* **HTML response**:  
```  
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Application unavailable</title></head><body><h1>Application temporarily unavailable</h1><p>Please try again later.</p></body></html>  
```

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone entry point ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_custom_errors/entrypoint" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "html_response_500_to_503",

            "action": "serve_error",

            "action_parameters": {

                "content": "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Application unavailable</title></head><body><h1>Application temporarily unavailable</h1><p>Please try again later.</p></body></html>",

                "content_type": "text/html",

                "status_code": 503

            },

            "expression": "http.response.code eq 500",

            "enabled": true

        }

    ]

  }'


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

This `PUT` request, corresponding to the [Update a zone entry point ruleset](https://developers.cloudflare.com/api/resources/rulesets/subresources/phases/methods/update/) operation, replaces any existing rules in the `http_custom_errors` phase entry point ruleset.

### Custom HTML response for Cloudflare 1020 errors

This example configures a custom HTML error response for [Cloudflare error 1020](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/error-1020/) (Access Denied).

* [ Dashboard ](#tab-panel-6001)
* [ API ](#tab-panel-6002)

**Custom error rule configuration:**

* **Name**: `Custom HTML response for 1020 errors`
* **If incoming requests match** \> **Custom filter expression**  
Use the Expression Editor:  
`(cf.response.1xxx_code eq 1020)`
* **Response type**: _HTML response_
* **HTML response**:  
```  
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Access denied</title></head><body><h1>You do not have access to this page</h1><p>Contact us if you think this is an error.</p></body></html>  
```

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone entry point ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_custom_errors/entrypoint" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "html_response_cf_1020",

            "action": "serve_error",

            "action_parameters": {

                "content": "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><title>Access denied</title></head><body><h1>You do not have access to this page</h1><p>Contact us if you think this is an error.</p></body></html>",

                "content_type": "text/html"

            },

            "expression": "cf.response.1xxx_code eq 1020",

            "enabled": true

        }

    ]

  }'


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

This `PUT` request, corresponding to the [Update a zone entry point ruleset](https://developers.cloudflare.com/api/resources/rulesets/subresources/phases/methods/update/) operation, replaces any existing rules in the `http_custom_errors` phase entry point ruleset.

### Custom error asset created from a URL

This example configures a custom error rule returning a previously created custom error asset named `500_error_template` for responses with a `500` HTTP status code.

* [ Dashboard ](#tab-panel-6003)
* [ API ](#tab-panel-6004)

**Custom error rule configuration:**

* **Name**: `Serve asset for HTTP 500 errors`
* **If incoming requests match** \> **Custom filter expression**:  
| Field                | Operator | Value |  
| -------------------- | -------- | ----- |  
| Response Status Code | equal to | 500   |  
If using the Expression Editor:  
`(http.response.code eq 500)`
* **Response type**: _Custom error asset_
* **Asset**: `500_error_template`

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone entry point ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_custom_errors/entrypoint" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "serve_error_500_asset",

            "action": "serve_error",

            "action_parameters": {

                "asset_name": "500_error_template",

                "content_type": "text/html"

            },

            "expression": "http.response.code eq 500",

            "enabled": true

        }

    ]

  }'


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

This `PUT` request, corresponding to the [Update a zone entry point ruleset](https://developers.cloudflare.com/api/resources/rulesets/subresources/phases/methods/update/) operation, replaces any existing rules in the `http_custom_errors` phase entry point ruleset.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/custom-errors/","name":"Custom Errors"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/custom-errors/example-rules/","name":"Example custom error rules"}}]}
```

---

---
title: Error page types
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/custom-errors/reference/error-page-types.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Error page types

| Page type                                 | Description                                                                                                                                                                                                                                                                                                         | API identifier     |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| WAF block                                 | The page displayed when visitors are blocked by a [Web Application Firewall](https://developers.cloudflare.com/waf/) rule. This page returns a 403 status code.                                                                                                                                                     | waf\_block         |
| IP/Country block                          | The page displayed when a request originates from a [blocked IP address or country](https://developers.cloudflare.com/waf/tools/ip-access-rules/). This page returns a 403 status code.                                                                                                                             | ip\_block          |
| IP/Country challenge                      | Presents a challenge to visitors from specified IP addresses or countries. This page returns a 403 status code. For more information, refer to [IP Access rules](https://developers.cloudflare.com/waf/tools/ip-access-rules/).                                                                                     | country\_challenge |
| 500 class errors                          | 500 class error pages are displayed when a web server is unable to process a request. For more information, refer to [Cloudflare 5xx errors](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-5xx-errors/).                                                                   | 500\_errors        |
| 1000 class errors                         | 1000 class error pages are displayed when a domain’s configuration, security settings, or origin setup prevents Cloudflare from completing a request. For more information, refer to [Cloudflare 1xxx errors](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/). | 1000\_errors       |
| Managed challenge / I'm Under Attack Mode | Presents different types of challenges to a visitor depending on the nature of their request and your security settings. This page returns a 403 status code. For more information, refer to [Under Attack mode](https://developers.cloudflare.com/fundamentals/reference/under-attack-mode/).                      | managed\_challenge |
| Rate limiting block                       | Displayed to visitors when they have been blocked by a [rate limiting rule](https://developers.cloudflare.com/waf/rate-limiting-rules/). This page returns a 429 status code.                                                                                                                                       | ratelimit\_block   |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/custom-errors/","name":"Custom Errors"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/custom-errors/reference/","name":"Reference"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/custom-errors/reference/error-page-types/","name":"Error page types"}}]}
```

---

---
title: Error tokens
description: Each custom error token provides diagnostic information or specific functionality that appears on the error page. Certain error pages require a page-specific custom error token.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/custom-errors/reference/error-tokens.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Error tokens

## For Error Pages

Each custom error token provides diagnostic information or specific functionality that appears on the error page. Certain error pages require a page-specific custom error token.

To display a custom page for each error, create a separate page per error. For example, to create an error page for both **IP/Country Block** and **Interactive Challenge**, you must design and publish two separate pages.

The following custom error tokens are required by their respective error pages:

| Token                             | Required for                                                                                                             |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| ::CAPTCHA\_BOX::                  | Interactive Challenge Country Challenge (Managed Challenge)Managed Challenge / I'm Under Attack Mode (Interstitial Page) |
| ::IM\_UNDER\_ATTACK\_BOX::        | Non-Interactive Challenge                                                                                                |
| ::CLOUDFLARE\_ERROR\_500S\_BOX::  | 5XX Errors                                                                                                               |
| ::CLOUDFLARE\_ERROR\_1000S\_BOX:: | 1XXX Errors                                                                                                              |

Each custom error token has a default look and feel. However, you can use CSS to stylize each custom error tag using each tag's class ID. All the external resources like images, CSS, and scripts will be inlined during the process. As such, all external resources need to be available (that is, they must return `200 OK`) otherwise an error will be thrown.

## For Custom Error Assets, inline responses, and Error Pages

A custom error asset, inline response, or error page may also include the following error tokens, which will be replaced with their real values before sending the response to the visitor:

| Token          | Description                                                              |
| -------------- | ------------------------------------------------------------------------ |
| ::CLIENT\_IP:: | The visitor's IP address.                                                |
| ::RAY\_ID::    | A unique identifier given to every request that goes through Cloudflare. |
| ::GEO::        | The country or region associated with the visitor's IP address.          |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/custom-errors/","name":"Custom Errors"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/custom-errors/reference/","name":"Reference"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/custom-errors/reference/error-tokens/","name":"Error tokens"}}]}
```

---

---
title: Custom Errors parameters
description: Custom error rules define when a custom error gets triggered and the content that is served to visitors. Rule parameters are the following:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/custom-errors/reference/parameters.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Custom Errors parameters

## Custom error rules

[Custom error rules](https://developers.cloudflare.com/rules/custom-errors/#custom-error-rules) define when a custom error gets triggered and the content that is served to visitors. Rule parameters are the following:

### Response type

API name: _N/A_ (handled via [asset\_name](#asset) and [content\_type](#response) parameters)

The content type of the inline response to send to the website visitor (JSON, HTML, Text, or XML), or **Custom error asset** if sending the content of a custom error asset.

When using the API you must either set the `asset_name` or set both the `content_type` and `content` parameters. Refer to [JSON response / HTML response / Text response / XML response](#response).

### Response code

API name: **`status_code`** ` Integer ` Optional

The HTTP status code of the response. If provided, this value will override the current response status code.

The status code must be between `400` and `999`.

### Asset

API name: **`asset_name`** ` String ` Optional

The name of the [custom error asset](#custom-error-assets) you previously uploaded (in the dashboard, you can create an asset when creating the rule). The asset may include [error tokens](https://developers.cloudflare.com/rules/custom-errors/reference/error-tokens/) that will be replaced with real values before sending the error response to the visitor.

A custom error rule can only reference an asset defined in the same scope as the rule (that is, in the same zone or account).

In the dashboard, this parameter is only available when you select `Custom error asset` in **Response type**.

When using the API, you must provide either the `asset_name` or the `content` parameter.

### JSON response / HTML response / Text response / XML response

API names: **`content`** ` String ` Optional and **`content_type`** ` String ` Required

The response body to return. It can include [error tokens](https://developers.cloudflare.com/rules/custom-errors/reference/error-tokens/) that will be replaced with real values before sending the error response to the visitor.

You must provide either the `asset_name` or the `content` parameter.

The maximum content size is 10 KB.

When using the API you must also set the `content_type` parameter, which defines the content type of the returned response. The value must be one of the following:

* `text/html`
* `text/plain`
* `application/json`
* `text/xml`

Warning

If you create an HTML error response, make sure the `referrer` meta tag is not present in the HTML code since it will disrupt [Cloudflare challenges](https://developers.cloudflare.com/cloudflare-challenges/):

```

<meta name="referrer" (...) />


```

## Custom error assets

A [custom error asset](https://developers.cloudflare.com/rules/custom-errors/#custom-error-assets) corresponds to a web resource such as an HTML web page (including any referenced images, CSS, and JavaScript code) that Cloudflare fetches and saves based on a URL you provide, to be served to visitors as an error page.

Custom error assets have the following parameters:

### Asset name

API name: **`name`** ` String ` Required

The name of the custom error asset. Example value: `"500_error_template"`.

An asset name can contain the following characters:

* Uppercase and lowercase letters (`A-Z` and `a-z`)
* Numbers (`0-9`)
* The underscore (`_`) character

The maximum length is 200 characters.

### Description

API name: **`description`** ` String ` Optional

A string describing the custom error asset. Example value: `"Standard 5xx error template page"`.

### Asset address

API name: **`url`** ` String ` Required

The URL of the page you want Cloudflare to fetch and store, to be served later to visitors as error pages according to the configured [custom error rules](#custom-error-rules). Example value: `"https://example.com/errors/500.html"`.

When you create or update an asset and provide a URL, Cloudflare collects any images, CSS, and JavaScript code used in the page, minifies the content, and saves it internally.

The content of the page at the specified URL may include [error tokens](https://developers.cloudflare.com/rules/custom-errors/reference/error-tokens/) that will be replaced with real values before sending the error response to the visitor.

When using the dashboard, you can later trigger another fetch to get the latest version of the page along with its resources, and store it internally.

When using the API, if you update an asset and provide the same URL, Cloudflare will fetch the URL again, along with its resources, and store it internally.

The maximum asset size is 1.5 MB.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/custom-errors/","name":"Custom Errors"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/custom-errors/reference/","name":"Reference"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/custom-errors/reference/parameters/","name":"Custom Errors parameters"}}]}
```

---

---
title: Troubleshoot Error Pages issues
description: If Cloudflare cannot load your site or you have blocked the United States (US) via IP Access rules or WAF custom rules, publishing and previewing a custom error page might not work.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/custom-errors/troubleshooting.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Troubleshoot Error Pages issues

## Cannot preview error page

If Cloudflare cannot load your site or you have blocked the United States (US) via [IP Access rules](https://developers.cloudflare.com/waf/tools/ip-access-rules/) or [WAF custom rules](https://developers.cloudflare.com/waf/custom-rules/), publishing and previewing a custom error page might not work.

A common error might look like the following: `Error fetching page: Fetch failed, https://example.com/ipcountryblock.html returned 403 (Code: 1202)`.

Make sure that no WAF rule is blocking or challenging Custom Errors product when it is fetching the content of your custom error page.

## Error pages for blocked requests

If you block countries or IP addresses with an [IP Access rule](https://developers.cloudflare.com/waf/tools/ip-access-rules/), affected visitors will get a [1005 error](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/error-1005/) and your **IP/Country Block** custom page.

If you block countries or IP addresses with a [WAF custom rule](https://developers.cloudflare.com/waf/custom-rules/) and you do not configure a [custom error rule](https://developers.cloudflare.com/rules/custom-errors/create-rules/#create-a-custom-error-rule-dashboard) or a [WAF custom response](https://developers.cloudflare.com/waf/custom-rules/create-dashboard/#configure-a-custom-response-for-blocked-requests) for blocked requests, affected visitors will get your **WAF Block** page.

If you block requests due to a [rate limiting rule](https://developers.cloudflare.com/waf/rate-limiting-rules/) and you do not configure a [custom error rule](https://developers.cloudflare.com/rules/custom-errors/create-rules/#create-a-custom-error-rule-dashboard) or a [WAF custom response](https://developers.cloudflare.com/waf/rate-limiting-rules/create-zone-dashboard/#configure-a-custom-response-for-blocked-requests) for blocked requests, affected visitors will get your **429 Errors** page displaying a Cloudflare [1015 error](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/error-1015/).

If you block countries or IP addresses with a firewall rule (now deprecated), affected visitors will get your **1000 Class Errors** page.

## 1XXX errors

You cannot customize the following 1XXX errors via Error Pages:

* `1001` \- Unable to resolve
* `1003` \- Bad Host header
* `1018` \- Unable to resolve because of ownership lookup failure
* `1023` \- Unable to resolve because of feature lookup failure

## Custom error page size

Your custom error page cannot be blank and the combined size of all page assets cannot exceed 1.5 MB (1,500,000 characters). To avoid exceeding the custom error page limit, preview your page to check its size before publishing.

## General troubleshooting advice

If you encounter errors while attempting to preview or publish your custom error page, use an [HTML validator ↗](https://validator.w3.org/) to ensure that your code resolves properly.

## More resources

* [HTTP Status Codes](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/)
* [Challenges](https://developers.cloudflare.com/cloudflare-challenges/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/custom-errors/","name":"Custom Errors"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/custom-errors/troubleshooting/","name":"Troubleshoot Error Pages issues"}}]}
```

---

---
title: Compression Rules
description: Use Compression Rules to customize the compression applied to responses from Cloudflare's global network to your website visitors, based on the file extension and content type. Compression Rules are powered by the Ruleset Engine.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/compression-rules/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Compression Rules

Use Compression Rules to customize the compression applied to responses from Cloudflare's global network to your website visitors, based on the file extension and content type. Compression Rules are powered by the [Ruleset Engine](https://developers.cloudflare.com/ruleset-engine/).

Cloudflare [compresses some responses by default](https://developers.cloudflare.com/speed/optimization/content/compression/), based on the content type. With Compression Rules, you can customize the default behavior, which includes defining preferred compression algorithms for particular file types.

When there is a match for a compression rule configured with several compression algorithms, the selected algorithm is the first one supported by the website visitor, according to the received `accept-encoding` HTTP header. If multiple compression rules match, the last rule wins.

Note

Compression Rules require that you [proxy the DNS records](https://developers.cloudflare.com/dns/proxy-status/) of your domain (or subdomain) through Cloudflare.

## Get started

Cloudflare provides you with rules templates for common use cases.

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Templates**, and then select one of the available templates.

You can also refer to the [Examples gallery](https://developers.cloudflare.com/rules/examples/) in the developer docs.

Alternatively, follow the instructions in the following pages to get started:

* [Create a compression rule in the dashboard](https://developers.cloudflare.com/rules/compression-rules/create-dashboard/)
* [Create a compression rule via Cloudflare API](https://developers.cloudflare.com/rules/compression-rules/create-api/)

---

## Availability

Compression Rules are available in all Cloudflare plans.

| Free            | Pro | Business | Enterprise |     |
| --------------- | --- | -------- | ---------- | --- |
| Availability    | Yes | Yes      | Yes        | Yes |
| Number of rules | 10  | 25       | 50         | 300 |

## Relevant fields

The following fields are commonly used in expressions of compression rules:

| Field in [Expression Builder](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/#expression-builder) | Field name                                                                                                                                                             |
| ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| _Media Type_                                                                                                                                    | [http.response.content\_type.media\_type](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.response.content%5Ftype.media%5Ftype/) |
| _File extension_                                                                                                                                | [http.request.uri.path.extension](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.request.uri.path.extension/)                   |
| N/A                                                                                                                                             | [raw.http.request.uri.path.extension](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/raw.http.request.uri.path.extension/)           |

## Important remarks

* If there is a match for a compression rule but the client does not support any of the compression algorithms configured in the rule (according to the provided `accept-encoding` request header), the response sent to the client will not be compressed.
* If there is a match for a compression rule but the response sent from the origin server contains a `cache-control: no-transform` HTTP header, the compression rule will not perform any changes to the response.

## Troubleshooting

When troubleshooting Compression Rules, use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to determine if a rule is triggering for a specific URL.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/compression-rules/","name":"Compression Rules"}}]}
```

---

---
title: Create a compression rule via API
description: Use the Rulesets API to create a compression rule via API.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/compression-rules/create-api.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a compression rule via API

Use the [Rulesets API](https://developers.cloudflare.com/ruleset-engine/rulesets-api/) to create a compression rule via API.

## Basic rule settings

When creating a compression rule via API, make sure you:

* Set the rule action to `compress_response`.
* Define the parameters in the `action_parameters` field according to the [settings](https://developers.cloudflare.com/rules/compression-rules/settings/#api-configuration-settings) you wish to override for matching requests.
* Deploy the rule to the `http_response_compression` phase at the zone level.

## Procedure

Follow this workflow to create a compression rule for a given zone via API:

1. Use the [List zone rulesets](https://developers.cloudflare.com/api/resources/rulesets/methods/list/) operation to check if there is already a ruleset for the `http_response_compression` phase at the zone level.
2. If the phase ruleset does not exist, create it using the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) operation. In the new ruleset properties, set the following values:  
   * **kind**: `zone`  
   * **phase**: `http_response_compression`
3. Use the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation to add a compression rule to the list of ruleset rules. Alternatively, include the rule in the [Create a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/create/) request mentioned in the previous step.

## Examples

For example API requests, refer to the [Examples gallery](https://developers.cloudflare.com/rules/compression-rules/examples/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/compression-rules/","name":"Compression Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/compression-rules/create-api/","name":"Create a compression rule via API"}}]}
```

---

---
title: Create a compression rule in the dashboard
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/compression-rules/create-dashboard.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Create a compression rule in the dashboard

1. In the Cloudflare dashboard, go to the Rules **Overview** page.  
[ Go to **Overview** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview)
2. Select **Create rule** \> **Compression Rule**.
3. (Optional) Select one of the rule templates that address common use cases. Then, review and adjust the proposed rule configuration.
4. Enter a descriptive name for the rule in **Rule name**.
5. Under **When incoming requests match**, select if you wish to apply the rule to [default content types](https://developers.cloudflare.com/speed/optimization/content/compression/#compression-between-cloudflare-and-website-visitors) (content types that Cloudflare compresses by default), or to requests that match a custom filter expression.
6. (Optional) To define a custom expression, use the Expression Builder (specifying one or more values for **Field**, **Operator**, and **Value**) or manually enter an expression using the Expression Editor. For more information, refer to [Edit expressions in the dashboard](https://developers.cloudflare.com/ruleset-engine/rules-language/expressions/edit-expressions/).
7. Under **Compression options**, set the [compression options](https://developers.cloudflare.com/rules/compression-rules/settings/#dashboard-configuration-settings).
8. To save and deploy your rule, select **Deploy**. If you are not ready to deploy your rule, select **Save as Draft**.  
If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to [Troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/#this-rule-may-not-apply-to-your-traffic) for more information.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/compression-rules/","name":"Compression Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/compression-rules/create-dashboard/","name":"Create a compression rule in the dashboard"}}]}
```

---

---
title: Compression Rules examples
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/compression-rules/examples/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Compression Rules examples

[Disable Brotli compressionCreate a compression rule to turn off Brotli compression for all incoming requests of a given zone.](https://developers.cloudflare.com/rules/compression-rules/examples/disable-all-brotli/)[Disable compression for AVIF imagesCreate a compression rule to turn off compression for AVIF images, based on either the content type or the file extension specified in the request.](https://developers.cloudflare.com/rules/compression-rules/examples/disable-compression-avif/)[Enable Zstandard compression for default content typesCreate a compression rule to turn on Zstandard compression for response content types where Cloudflare applies compression by default.](https://developers.cloudflare.com/rules/compression-rules/examples/enable-zstandard/)[Use Gzip compression for CSV filesCreate a compression rule to set Gzip compression as the preferred compression method for CSV files.](https://developers.cloudflare.com/rules/compression-rules/examples/gzip-for-csv/)[Use only Brotli compression for a specific pathCreate a compression rule to set Brotli as the only supported compression algorithm for a specific URI path.](https://developers.cloudflare.com/rules/compression-rules/examples/only-brotli-url-path/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/compression-rules/","name":"Compression Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/compression-rules/examples/","name":"Compression Rules examples"}}]}
```

---

---
title: Disable Brotli compression
description: Create a compression rule to turn off Brotli compression for all incoming requests of a given zone.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/compression-rules/examples/disable-all-brotli.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Disable Brotli compression

Create a compression rule to turn off Brotli compression for all incoming requests of a given zone.

* [ Dashboard ](#tab-panel-5985)
* [ API ](#tab-panel-5986)

The following example rule will disable Brotli compression for all incoming requests of a given zone. The only available compression algorithm will be Gzip.

**When incoming requests match**

* All incoming requests

**Then**

* **Compression options**: Custom
* **Define a custom order for compression types**: `Gzip`

If the client does not support Gzip compression, the response will be uncompressed.

The following example sets the rules of an existing [entry point ruleset](https://developers.cloudflare.com/ruleset-engine/about/rulesets/#entry-point-ruleset) (with ID `{ruleset_id}`) for the `http_response_compression` phase to a single compression rule, using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "always_use_gzip",

            "expression": "true",

            "action": "compress_response",

            "action_parameters": {

                "algorithms": [

                    {

                        "name": "gzip"

                    }

                ]

            }

        }

    ]

  }'


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/compression-rules/","name":"Compression Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/compression-rules/examples/","name":"Compression Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/compression-rules/examples/disable-all-brotli/","name":"Disable Brotli compression"}}]}
```

---

---
title: Disable compression for AVIF images
description: Create a compression rule to turn off compression for AVIF images, based on either the content type or the file extension specified in the request.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/compression-rules/examples/disable-compression-avif.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Disable compression for AVIF images

Create a compression rule to turn off compression for AVIF images, based on either the content type or the file extension specified in the request.

* [ Dashboard ](#tab-panel-5987)
* [ API ](#tab-panel-5988)

The following example rule will disable compression for AVIF images, based on either the content type or the file extension specified in the request.

**When incoming requests match**

* Custom filter expression:  
   * _Media Type_ _equals_ `image/avif` **OR**  
   * _File extension_ _equals_ `avif`

**Then**

* **Compression options** \> _Disable compression_

The following example sets the rules of an existing [entry point ruleset](https://developers.cloudflare.com/ruleset-engine/about/rulesets/#entry-point-ruleset) (with ID `{ruleset_id}`) for the `http_response_compression` phase to a single compression rule, using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "disable_compression_for_avif",

            "expression": "http.response.content_type.media_type eq \"image/avif\" or http.request.uri.path.extension eq \"avif\"",

            "action": "compress_response",

            "action_parameters": {

                "algorithms": [

                    {

                        "name": "none"

                    }

                ]

            }

        }

    ]

  }'


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/compression-rules/","name":"Compression Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/compression-rules/examples/","name":"Compression Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/compression-rules/examples/disable-compression-avif/","name":"Disable compression for AVIF images"}}]}
```

---

---
title: Enable Zstandard compression for default content types
description: Create a compression rule to turn on Zstandard compression for response content types where Cloudflare applies compression by default.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/compression-rules/examples/enable-zstandard.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Enable Zstandard compression for default content types

Create a compression rule to turn on Zstandard compression for response content types where Cloudflare applies compression by default.

* [ Dashboard ](#tab-panel-5989)
* [ API ](#tab-panel-5990)

The following example rule will turn on Zstandard compression for response content types where [Cloudflare applies compression by default](https://developers.cloudflare.com/speed/optimization/content/compression/). If the client does not support Zstandard compression, it will use Brotli or Gzip compression as a fallback.

**When incoming requests match**

* Custom filter expression:  
   * _Media Type_ _is in_ `text/html, text/richtext, text/plain, text/css, text/x-script, text/x-component, text/x-java-source, text/x-markdown, application/javascript, application/x-javascript, text/javascript, text/js, image/x-icon, image/vnd.microsoft.icon, application/x-perl, application/x-httpd-cgi, text/xml, application/xml, application/rss+xml, application/vnd.api+json, application/x-protobuf, application/json, multipart/bag, multipart/mixed, application/xhtml+xml, font/ttf, font/otf, font/x-woff, image/svg+xml, application/vnd.ms-fontobject, application/ttf, application/x-ttf, application/otf, application/x-otf, application/truetype, application/opentype, application/x-opentype, application/font-woff, application/eot, application/font, application/font-sfnt, application/wasm, application/javascript-binast, application/manifest+json, application/ld+json, application/graphql+json, application/geo+json`

**Then**

* **Compression options**: Custom
* **Define a custom order for compression types**: `Zstandard`, `Brotli`, `Gzip`

The following example sets the rules of an existing [entry point ruleset](https://developers.cloudflare.com/ruleset-engine/about/rulesets/#entry-point-ruleset) (with ID `{ruleset_id}`) for the `http_response_compression` phase to a single compression rule, using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "use_zstd_compression",

            "expression": "(http.response.content_type.media_type in {\"text/html\" \"text/richtext\" \"text/plain\" \"text/css\" \"text/x-script\" \"text/x-component\" \"text/x-java-source\" \"text/x-markdown\" \"application/javascript\" \"application/x-javascript\" \"text/javascript\" \"text/js\" \"image/x-icon\" \"image/vnd.microsoft.icon\" \"application/x-perl\" \"application/x-httpd-cgi\" \"text/xml\" \"application/xml\" \"application/rss+xml\" \"application/vnd.api+json\" \"application/x-protobuf\" \"application/json\" \"multipart/bag\" \"multipart/mixed\" \"application/xhtml+xml\" \"font/ttf\" \"font/otf\" \"font/x-woff\" \"image/svg+xml\" \"application/vnd.ms-fontobject\" \"application/ttf\" \"application/x-ttf\" \"application/otf\" \"application/x-otf\" \"application/truetype\" \"application/opentype\" \"application/x-opentype\" \"application/font-woff\" \"application/eot\" \"application/font\" \"application/font-sfnt\" \"application/wasm\" \"application/javascript-binast\" \"application/manifest+json\" \"application/ld+json\" \"application/graphql+json\" \"application/geo+json\"})",

            "action": "compress_response",

            "action_parameters": {

                "algorithms": [

                    {

                        "name": "zstd"

                    },

                    {

                        "name": "brotli"

                    },

                    {

                        "name": "gzip"

                    }

                ]

            }

        }

    ]

  }'


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/compression-rules/","name":"Compression Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/compression-rules/examples/","name":"Compression Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/compression-rules/examples/enable-zstandard/","name":"Enable Zstandard compression for default content types"}}]}
```

---

---
title: Use Gzip compression for CSV files
description: Create a compression rule to set Gzip compression as the preferred compression method for CSV files.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/compression-rules/examples/gzip-for-csv.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Use Gzip compression for CSV files

Create a compression rule to set Gzip compression as the preferred compression method for CSV files.

* [ Dashboard ](#tab-panel-5991)
* [ API ](#tab-panel-5992)

The following example rule will configure Gzip compression as the preferred compression method for CSV files. If the visitor does not support this algorithm, Cloudflare will try to compress the response using a different algorithm supported by the visitor.

**When incoming requests match**

* Custom filter expression:  
   * _File extension_ _equals_ `csv`

**Then**

* **Compression options**: Custom
* **Define a custom order for compression types**: `Gzip`, `Auto`

The following example sets the rules of an existing [entry point ruleset](https://developers.cloudflare.com/ruleset-engine/about/rulesets/#entry-point-ruleset) (with ID `{ruleset_id}`) for the `http_response_compression` phase to a single compression rule, using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "use_gzip_for_csv",

            "expression": "http.request.uri.path.extension eq \"csv\"",

            "action": "compress_response",

            "action_parameters": {

                "algorithms": [

                    {

                        "name": "gzip"

                    },

                    {

                        "name": "auto"

                    }

                ]

            }

        }

    ]

  }'


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/compression-rules/","name":"Compression Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/compression-rules/examples/","name":"Compression Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/compression-rules/examples/gzip-for-csv/","name":"Use Gzip compression for CSV files"}}]}
```

---

---
title: Use only Brotli compression for a specific path
description: Create a compression rule to set Brotli as the only supported compression algorithm for a specific URI path.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/compression-rules/examples/only-brotli-url-path.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Use only Brotli compression for a specific path

Create a compression rule to set Brotli as the only supported compression algorithm for a specific URI path.

* [ Dashboard ](#tab-panel-5993)
* [ API ](#tab-panel-5994)

The following example rule will configure only Brotli compression for a specific URI path.

**When incoming requests match**

* Custom filter expression:  
   * _URI Path_ _equals_ `/download/assets.tar`

**Then**

* **Compression options**: Custom
* **Define a custom order for compression types**: `Brotli`

Since the rule configuration does not include _Auto_ at the end of the custom algorithms list, the response will be uncompressed if the web visitor does not support Brotli.

The following example sets the rules of an existing [entry point ruleset](https://developers.cloudflare.com/ruleset-engine/about/rulesets/#entry-point-ruleset) (with ID `{ruleset_id}`) for the `http_response_compression` phase to a single compression rule, using the [Update a zone ruleset](https://developers.cloudflare.com/api/resources/rulesets/methods/update/) operation:

Required API token permissions

At least one of the following [token permissions](https://developers.cloudflare.com/fundamentals/api/reference/permissions/)is required:
* `Response Compression Write`
* `Config Settings Write`
* `Dynamic URL Redirects Write`
* `Cache Settings Write`
* `Custom Errors Write`
* `Origin Write`
* `Managed headers Write`
* `Zone Transform Rules Write`
* `Mass URL Redirects Write`
* `Magic Firewall Write`
* `L4 DDoS Managed Ruleset Write`
* `HTTP DDoS Managed Ruleset Write`
* `Sanitize Write`
* `Transform Rules Write`
* `Select Configuration Write`
* `Bot Management Write`
* `Zone WAF Write`
* `Account WAF Write`
* `Account Rulesets Write`
* `Logs Write`
* `Logs Write`

Update a zone ruleset

```

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID" \

  --request PUT \

  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \

  --json '{

    "rules": [

        {

            "ref": "use_only_brotli_for_assets_tar",

            "expression": "http.request.uri.path eq \"/download/assets.tar\"",

            "action": "compress_response",

            "action_parameters": {

                "algorithms": [

                    {

                        "name": "brotli"

                    }

                ]

            }

        }

    ]

  }'


```

Use the `ref` field to get stable rule IDs across updates when using Terraform. Adding this field prevents Terraform from recreating the rule on changes. For more information, refer to [Troubleshooting](https://developers.cloudflare.com/terraform/troubleshooting/rule-id-changes/#how-to-keep-the-same-rule-id-between-modifications) in the Terraform documentation.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/compression-rules/","name":"Compression Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/compression-rules/examples/","name":"Compression Rules examples"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/compression-rules/examples/only-brotli-url-path/","name":"Use only Brotli compression for a specific path"}}]}
```

---

---
title: Compression Rules settings
description: Compression Rules support the configuration settings covered in the following sections.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/compression-rules/settings.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Compression Rules settings

Compression Rules support the configuration settings covered in the following sections.

## Dashboard configuration settings

### Enable Zstandard (Zstd) compression Beta

Sets Zstandard as the preferred compression algorithm. If it is not supported, will automatically fall back to Brotli, Gzip, or uncompressed data.

### Enable Brotli and Gzip compression

Enables Cloudflare's default compression setting. Brotli is the preferred compression algorithm. It will automatically fall back to Gzip or to uncompressed data.

### Disable compression

Disables compression for matching requests. Also disables Cloudflare's [default compression behavior](https://developers.cloudflare.com/speed/optimization/content/compression/).

### Custom

Defines a custom order for compression algorithms.

Allowed values are the following:

* **Gzip**: Use the Gzip compression algorithm, if supported by the website visitor.
* **Brotli**: Use the Brotli compression algorithm, if supported by the website visitor.
* **Zstandard**: Use the Zstandard (Zstd) compression algorithm, if supported by the website visitor.
* **Auto**: Compress the response according to the algorithms supported by the website visitor (if any). Cloudflare will define the order of preference for the compression algorithms, which may change in the future. Has the same behavior of the **Enable compression** option.
* **Default**: Use Cloudflare's [default compression behavior](https://developers.cloudflare.com/speed/optimization/content/compression/), which depends on the response content type.

If you specify only _Gzip_, _Brotli_, or _Zstandard_ and no algorithm matches, the response will have no compression. To configure a fallback compression mechanism, add _Auto_ to the list.

Note

The compression applied by the _Default_ option takes into account any configured compression rules that match incoming requests.

---

## API configuration settings

The configuration object supported by the `compress_response` action has the following format:

```

"action_parameters": {

  "algorithms": [

    { "name": "<VALUE1>" },

    { "name": "<VALUE2>" },

    // ...

  ]

}


```

The `algorithms` list must contain at least one item.

The supported algorithm values are:

* `gzip`: Use the Gzip compression algorithm, if supported by the website visitor.
* `brotli`: Use the Brotli compression algorithm, if supported by the website visitor.
* `zstd`: Use the Zstandard compression algorithm, if supported by the website visitor.
* `none`: Do not use any compression algorithm.
* `auto`: Compress the response according to the algorithms supported by the website visitor (if any). Cloudflare will define the order of preference for the compression algorithms, which may change in the future.
* `default`: Use Cloudflare's [default compression behavior](https://developers.cloudflare.com/speed/optimization/content/compression/#compression-between-cloudflare-and-website-visitors), which depends on the response content type.

If you include `none`, `default`, or `auto` in the list, it must be the last value in the list.

When you specify only the `gzip`, `brotli`, or `zstd` algorithms, if no algorithm matches then the response will have no compression. To configure a fallback compression mechanism, add `auto` to the list.

For API examples, refer to the [Examples gallery](https://developers.cloudflare.com/rules/compression-rules/examples/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/compression-rules/","name":"Compression Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/compression-rules/settings/","name":"Compression Rules settings"}}]}
```

---

---
title: Page Rules
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/page-rules/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Page Rules

Page Rules trigger one or more actions whenever a certain URL pattern is matched. Page Rules are available in **Rules** \> **Page Rules**.

## Availability

The default number of allowed page rules depends on the domain plan as shown below.

| Free            | Pro | Business | Enterprise |     |
| --------------- | --- | -------- | ---------- | --- |
| Availability    | Yes | Yes      | Yes        | Yes |
| Number of rules | 3   | 20       | 50         | 125 |

---

## Before getting started

It is important to understand a few Page Rules behaviors.

### Page Rules require proxied DNS records

Page Rules require a [proxied](https://developers.cloudflare.com/dns/proxy-status/) DNS record for your page rule to work. Page Rules will not apply to hostnames that do not exist in DNS or are not being directed to Cloudflare.

Depending on the record type, you can use different values for the target as a placeholder. Either one of these achieves the same outcome and you only need to create one:

```

www.example.com  A      192.0.2.1

www.example.com  AAAA   2001:DB8::1

www.example.com  CNAME  domain.example


```

Cloudflare recommends only using reserved IP addresses or domain names to avoid sending traffic to foreign infrastructure.

For more information on reserved IP addresses or top level domains, please refer to these RFCs:

* [RFC 5737 ↗](https://datatracker.ietf.org/doc/html/rfc5737)
* [RFC 3849 ↗](https://datatracker.ietf.org/doc/html/rfc3849)
* [RFC 2606 ↗](https://datatracker.ietf.org/doc/html/rfc2606)

### Priority order matters

Only the highest priority matching page rule takes effect on a request.

Page Rules are prioritized in descending order in the Cloudflare dashboard, with the highest priority rule at the top. For this reason, Cloudflare recommends ordering your rules from most specific to least specific.

A page rule matches a URL pattern based on the following format (comprised of five segments):

```

<SCHEME>://<HOSTNAME>:<PORT>/<PATH>?<QUERY_STRING>


```

An example URL with all the segments looks like the following:

```

https://www.example.com:443/image.png?parameter1=value1


```

The `<SCHEME>` and `<PORT>` segments are optional. If omitted, `<SCHEME>` matches both `http://` and `https://` protocols. If no `<PORT>` is specified, the rule will match all ports.

### Disabled page rules

When a page rule is disabled, actions will not trigger, but the rule will:

* Still appear in the Cloudflare dashboard.
* Be editable.
* Count against the number of rules allowed for your domain.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/page-rules/","name":"Page Rules"}}]}
```

---

---
title: URL forwarding with Page Rules
description: Page Rules allow you to forward or redirect traffic to a different URL, though they are just one of the options provided by Cloudflare.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/page-rules/how-to/url-forwarding.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# URL forwarding with Page Rules

Page Rules allow you to forward or redirect traffic to a different URL, though they are just one of the [options provided by Cloudflare](https://developers.cloudflare.com/fundamentals/reference/redirects/).

Note

Consider alternative [Rules](https://developers.cloudflare.com/rules/) options due to their enhanced configurability. Refer to the [migration guide](https://developers.cloudflare.com/rules/reference/page-rules-migration/) for details.

For more flexibility and customization, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

---

## Redirect with Page Rules

To configure URL forwarding or redirects using Page Rules:

1. In the Cloudflare dashboard, go to the **Page Rules** page.  
[ Go to **Page Rules** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/page-rules)
2. Select **Create Page Rule**.
3. Under **If the URL matches**, enter the URL or URL pattern that should match the rule.
4. In **Pick a Setting**, choose **Forwarding URL** from the drop-down menu.
5. For **Select status code**, choose _301 - Permanent Redirect_ or _302 - Temporary Redirect_.
6. Enter the destination URL.
7. Select **Save and Deploy Page Rule**.

Note

Page Rules require a [proxied DNS record](https://developers.cloudflare.com/dns/proxy-status/) to work. Page Rules will not apply to subdomains that do not exist in DNS or are not being directed to Cloudflare.

---

## Forwarding examples

Imagine you want site visitors to reach your website for a variety of URL patterns. For instance, the page rule URL patterns `*www.example.com/products` and `*example.com/products` match:

```

http://example.com/products


http://www.example.com/products


https://www.example.com/products


https://blog.example.com/products


https://www.blog.example.com/products


```

but do not match:

```

http://www.example.com/blog/products (extra directory)

or

http://www.example.comproducts (no trailing slash)


```

Once you have created the pattern that matches what you want, select the **Forwarding** toggle. This will display a field where you can enter the address you want requests forwarded to.

```

https://example.com/products


```

If you enter the address above in the forwarding box and select **Add Rule**, within a few seconds any requests that match the pattern you entered will automatically be forwarded with an `HTTP 302` redirect status code to the new URL.

---

## Advanced forwarding options

If you use a basic redirect, such as forwarding the apex domain (`example.com`) to `www.example.com`, then you lose anything else in the URL.

For example, you could set up the pattern:

```

example.com


```

And have it forward to:

```

http://www.example.com


```

However, if someone entered `example.com/some-particular-page.html`, they would be redirected to:

```

www.example.com


```

Instead of:

```

www.example.com/some-particular-page.html


```

The solution is to use variables. Each wildcard corresponds to a variable when can be referenced in the forwarding address. The variables are represented by a `$` (dollar sign) followed by a number. To refer to the first wildcard you would use `$1`, to refer to the second wildcard you would use `$2`, and so on.

To fix the forwarding from the apex to `www` in the above example, you could use the same pattern:

```

example.com/*


```

You would then set up the following URL for traffic to forward to:

```

http://www.example.com/$1


```

In this case, if someone went to:

```

example.com/some-particular-page.html


```

They would be redirected to:

```

http://www.example.com/some-particular-page.html


```

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/page-rules/","name":"Page Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/page-rules/how-to/","name":"How to"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/page-rules/how-to/url-forwarding/","name":"URL forwarding with Page Rules"}}]}
```

---

---
title: Manage Page Rules
description: You can manage Page Rules in the Cloudflare dashboard or via API.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/page-rules/manage.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Manage Page Rules

You can manage Page Rules in the Cloudflare dashboard or via API.

Note

Consider alternative [Rules](https://developers.cloudflare.com/rules/) options due to their enhanced configurability. Refer to the [migration guide](https://developers.cloudflare.com/rules/reference/page-rules-migration/) for details.

For more flexibility and customization, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

## Create a page rule

* [ Dashboard ](#tab-panel-6013)
* [ API ](#tab-panel-6014)

To create a page rule in the dashboard:

1. In the Cloudflare dashboard, go to the **Page Rules** page.  
[ Go to **Page Rules** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/page-rules)
2. Select **Create Page Rule**.
3. For **URL**, enter the URL or URL pattern that should match the rule ([more details about wildcard matching](https://developers.cloudflare.com/rules/page-rules/reference/wildcard-matching/)).
4. For **Pick a Setting**, select a [Cloudflare setting](https://developers.cloudflare.com/rules/page-rules/reference/settings/) to adjust. If desired, select **Add a Setting** to adjust multiple Cloudflare settings with the same rule.
5. In the **Order** dropdown, specify the desired order: _First, Last_ or _Custom_.
6. To save and deploy your rule, select **Save and Deploy Page Rule**. If you are not ready to deploy your rule, select **Save as Draft**.  
If you are matching a hostname in your rule expression, you may be prompted to create a proxied DNS record for that hostname. Refer to [Troubleshooting](https://developers.cloudflare.com/rules/reference/troubleshooting/#this-rule-may-not-apply-to-your-traffic) for more information.

For ideas about what rules you can create, refer to [Recommended page rules](https://developers.cloudflare.com/rules/page-rules/reference/recommended-rules/).

To create a page rule using the API, send a [POST request](https://developers.cloudflare.com/api/resources/page%5Frules/methods/create/).

You may also want to review the documentation on [wildcard matching](https://developers.cloudflare.com/rules/page-rules/reference/wildcard-matching/), [available settings](https://developers.cloudflare.com/rules/page-rules/reference/settings/), and [recommended rules](https://developers.cloudflare.com/rules/page-rules/reference/recommended-rules/).

Notes

* Page Rules require a [proxied DNS record](https://developers.cloudflare.com/dns/proxy-status/) to work. Page Rules will not apply to subdomains that do not exist in DNS or are not being directed to Cloudflare.
* Cloudflare does not support non-ASCII characters — such as punycode/unicode domain — in Page Rules. Instead, you could URL-encode the string using [Punycode converter ↗](https://www.punycoder.com/).

## Edit a page rule

* [ Dashboard ](#tab-panel-6009)
* [ API ](#tab-panel-6010)

To edit a page rule in the dashboard:

1. In the Cloudflare dashboard, go to the **Page Rules** page.  
[ Go to **Page Rules** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/page-rules)
2. For a specific rule:  
   * To enable or disable the rule, select the on/off toggle.  
   * To modify the URL pattern, settings, and order, select **Edit** (wrench icon). Then, enter the information you want to change.

To update one or more fields using the API, send a [PATCH request](https://developers.cloudflare.com/api/resources/page%5Frules/methods/edit/).

To entirely replace the configuration of a page rule, send a [PUT request](https://developers.cloudflare.com/api/resources/page%5Frules/methods/update/).

## Delete a page rule

* [ Dashboard ](#tab-panel-6011)
* [ API ](#tab-panel-6012)

To delete a page rule in the dashboard:

1. In the Cloudflare dashboard, go to the **Page Rules** page.  
[ Go to **Page Rules** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/page-rules)
2. For a specific rule, select **X**. Then, select **Delete**.

To delete a page rule using the API, send a [DELETE request](https://developers.cloudflare.com/api/resources/page%5Frules/methods/delete/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/page-rules/","name":"Page Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/page-rules/manage/","name":"Manage Page Rules"}}]}
```

---

---
title: Additional reference for Page Rules
description: This setting is available to Business and Enterprise customers.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/page-rules/reference/additional-reference.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Additional reference for Page Rules

Note

Consider alternative [Rules](https://developers.cloudflare.com/rules/) options due to their enhanced configurability. Refer to the [migration guide](https://developers.cloudflare.com/rules/reference/page-rules-migration/) for details.

For more flexibility and customization, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

## Bypass Cache on Cookie setting

This setting is available to Business and Enterprise customers.

The **Bypass Cache on Cookie** setting supports basic regular expressions (regex) as follows:

* A pipe operator (represented by `|`) to match multiple cookies using _OR_ boolean logic. For example, `bypass=.*|PHPSESSID=.*` would bypass the cache if either a cookie called `bypass` or `PHPSESSID` were set, regardless of the cookie's value.
* The wildcard operator (represented by `.*`), such that a rule value of `t.*st=` would match both a cookie called `test` and one called `teeest`.

Limitations include:

* 150 characters per cookie regex
* 12 wildcards per cookie regex
* 1 wildcard in between each `|` in the cookie regex

To learn how to configure **Bypass Cache on Cookie** with a cache rule, refer to [Bypass Cache on Cookie](https://developers.cloudflare.com/cache/how-to/cache-rules/examples/bypass-cache-on-cookie/).

Note

If you add both this setting and the enterprise-only _Cache On Cookie_ setting to the same page rule, _Cache On Cookie_ takes precedence over _Bypass Cache on Cookie_.

## Zone name occurrences must end with a slash

When saving a page rule, Cloudflare will ensure that there is a slash after each occurrence of the current zone name in the **If the URL matches** field. For example, if the current zone name is `example.com`, then:

* `example.com` will be saved as `example.com/`
* `example.com/path/example.com` will be saved as `example.com/path/example.com/`

Note that `example.com/some-path/cloudflare.com` will be saved _without_ a final slash, since the zone name is not `cloudflare.com`.

## Network ports supported by Page Rules

If you specify a port in the **If the URL matches** field of a page rule, it must be one of the following:

* One of the HTTP/HTTPS ports [compatible with Cloudflare’s proxy](https://developers.cloudflare.com/fundamentals/reference/network-ports/#network-ports-compatible-with-cloudflares-proxy).
* A custom port of a [Cloudflare Spectrum](https://developers.cloudflare.com/spectrum/) HTTPS application.

## Using Page Rules with Workers

If the URL of the current request matches both a page rule and a [Workers custom route](https://developers.cloudflare.com/workers/configuration/routing/routes/), some Pages Rules settings will not be applied. For more details, refer to [Page Rules](https://developers.cloudflare.com/workers/configuration/workers-with-page-rules/).

## Page Rules are case-insensitive

The pattern entered under **If the URL matches** will not consider upper and lower case differences — `example.com/path`, `example.com/Path`, and `example.com/PATH` will be triggered the same way.

If you need your rules to consider case sensitivity, you might want to use alternative [Rules](https://developers.cloudflare.com/rules/) options instead.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/page-rules/","name":"Page Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/page-rules/reference/","name":"Reference"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/page-rules/reference/additional-reference/","name":"Additional reference for Page Rules"}}]}
```

---

---
title: Recommended page rules
description: Use Cloudflare Page Rules to improve the user experience of your domain with hardened security and enhanced site performance, while increasing reliability and minimizing bandwidth usage for your origin server.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/page-rules/reference/recommended-rules.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Recommended page rules

Use Cloudflare Page Rules to improve the user experience of your domain with hardened security and enhanced site performance, while increasing reliability and minimizing bandwidth usage for your origin server.

Note

Consider alternative [Rules](https://developers.cloudflare.com/rules/) options due to their enhanced configurability. Refer to the [migration guide](https://developers.cloudflare.com/rules/reference/page-rules-migration/) for details.

For more flexibility and customization, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

Keep in mind that not all rules will be right for everyone, but these are some of the most popular.

* 301/302 Forwarding URL
* Cache Level in specific paths
* Edge Cache TTL, Always Online, and Browser Cache TTL

### 301/302 Forwarding URL

Note

Consider using [Single Redirects](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/) or [Bulk Redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/) to forward or redirect traffic to a different URL due to ease of use, maintenance, and cost. You should only use Page Rules when Dynamic or Bulk Redirects do not meet your use case.

Two common examples for using forwarding URLs are:

* Defining the root as the canonical version of your domain.
* Directing visitors to a specific page with an easy to remember URL.

This example page rule configuration defines the root as the canonical version of your domain:

* **If the URL matches**: `*www.example.com/*`
* **Setting**: _Forwarding URL_ | **Select status code**: _301 Permanent Redirect_
* **Enter destination URL**: `https://example.com/$2`

This example redirects visitors to a specific page with an easy to remember URL:

* **If the URL matches**: `*www.example.com/fb*`
* **Setting**: _Forwarding URL_ | **Select status code**: _302 Temporary Redirect_
* **Enter destination URL**: `https://www.facebook.com/username`

### Cache Level in specific paths

Certain sections of a website, like the login or admin section, have different security and performance requirements than your general public-facing pages.

The following example page rule configuration bypasses cache for requests targeting a specific path:

* **If the URL matches**: `example.com/user*`
* **Setting**: _Cache Level_ | **Value**: _Bypass_

### Edge Cache TTL and Browser Cache TTL

Certain resources on your domain will likely not change often. For these resources, taking advantage of aggressive caching options can significantly reduce the load on your server and bandwidth utilization.

#### Examples

In the following example page rule configuration, the target is a folder that holds the majority of the image assets as well as some other types of multimedia.

* **If the URL matches**: `example.com/sites/default/files*`
* **Setting**: _Browser Cache TTL_ | **Value**: _a day_
* **Setting**: _Cache Level |_ **Value**: _Cache Everything_
* **Setting**: _Edge Cache TTL |_ **Value**: _7 days_

The following example page rule configuration applies unique rules for critical pages that do not change very often.

* **If the URL matches**: `example.com/terms-of-service`
* **Setting**: _Browser Cache TTL_ | **Value**: _a day_
* **Setting**: _Always Online |_ **Value**: _On_
* **Setting**: _Cache Level_ | **Value**: _Cache Everything_
* **Setting**: _Edge Cache TTL_ | **Value**: _a month_

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/page-rules/","name":"Page Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/page-rules/reference/","name":"Reference"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/page-rules/reference/recommended-rules/","name":"Recommended page rules"}}]}
```

---

---
title: Page Rules settings
description: Settings control the action Cloudflare takes once a request matches the URL pattern defined in a page rule. You can use settings to enable and disable multiple Cloudflare features across the dashboard.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/page-rules/reference/settings.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Page Rules settings

Settings control the action Cloudflare takes once a request matches the URL pattern defined in a page rule. You can use settings to enable and disable multiple Cloudflare features across the dashboard.

Note

Consider alternative [Rules](https://developers.cloudflare.com/rules/) options due to their enhanced configurability. Refer to the [migration guide](https://developers.cloudflare.com/rules/reference/page-rules-migration/) for details.

For more flexibility and customization, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

Note that:

* Some settings require a Pro, Business, or Enterprise domain plan.
* You can specify more than one setting to apply when the rule triggers.

The available Page Rules settings are the following:

| **Setting**                                                                                                                      | **Description**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | **Plans**               |
| -------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
| [Always Use HTTPS](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/always-use-https/)                 | Enable **Always Use HTTPS** feature. If enabled, any http:// URL is converted to https:// through a 301 redirect.If this option does not appear, you do not have an active **Edge Certificate**.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | All                     |
| [Automatic HTTPS Rewrites](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/automatic-https-rewrites/) | Turn on or off **Automatic HTTPS Rewrites**.NoteTo use this feature on specific hostnames - instead of across your entire zone - use a [configuration rule](https://developers.cloudflare.com/rules/configuration-rules/).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | All                     |
| [Browser Cache TTL](https://developers.cloudflare.com/cache/how-to/edge-browser-cache-ttl/)                                      | Control how long resources cached by client browsers remain valid. The Cloudflare dashboard and the API both prohibit setting **Browser Cache TTL** to 0 for non-Enterprise domains.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | All                     |
| [Browser Integrity Check](https://developers.cloudflare.com/waf/tools/browser-integrity-check/)                                  | Inspect the visitor's browser for headers commonly associated with spammers and certain bots.NoteTo use this feature on specific hostnames - instead of across your entire zone - use a [configuration rule](https://developers.cloudflare.com/rules/configuration-rules/).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | All                     |
| Bypass Cache on Cookie                                                                                                           | Bypass cache and fetch resources from the origin server if a regular expression matches against a cookie name present in the request.If you add both this setting and the _Cache On Cookie_ setting to the same page rule, _Cache On Cookie_ takes precedence over _Bypass Cache on Cookie_.Refer to the [Additional details](https://developers.cloudflare.com/rules/page-rules/reference/additional-reference/#bypass-cache-on-cookie-setting) to learn about limited regular expression support.                                                                                                                                                                                                                                                                                                                         | Business and Enterprise |
| [Cache By Device Type](https://developers.cloudflare.com/cache/how-to/cache-rules/examples/cache-device-type/)                   | Separate cached content based on the visitor’s device type.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | Enterprise              |
| [Cache Deception Armor](https://developers.cloudflare.com/cache/cache-security/cache-deception-armor/)                           | Protect from web cache deception attacks while still allowing static assets to be cached. This setting verifies that the URL's extension matches the returned _Content-Type_.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | All                     |
| Cache Level                                                                                                                      | Apply custom caching based on the option selected:– **Bypass**: Cloudflare does not cache.– **No Query String**: Delivers resources from cache when there is no query string.– **Ignore Query String**: Delivers the same resource to everyone independent of the query string.– **Standard**: Caches all static content that has a query string.– **Cache Everything**: Treats all content as static and caches all file types beyond the [Cloudflare default cached content](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#default-cached-file-extensions). Respects cache headers from the origin web server unless **Edge Cache TTL** is also set in the Page Rule. When combined with an **Edge Cache TTL** \> 0, **Cache Everything** removes cookies from the origin web server response. | All                     |
| Cache on Cookie                                                                                                                  | Apply the _Cache Everything_ option (_Cache Level_ setting) based on a regular expression match against a cookie name.If you add both this setting and _Bypass Cache on Cookie_ to the same page rule, _Cache On Cookie_ takes precedence over _Bypass Cache on Cookie_.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | Business and above      |
| [Cache TTL by Status Code](https://developers.cloudflare.com/cache/how-to/configure-cache-status-code/)                          | Enterprise customers can set cache time-to-live (TTL) based on the response status from the origin web server. Cache TTL refers to the duration of a resource in the Cloudflare network before being marked as stale or discarded from cache. Status codes are returned by a resource's origin. Setting cache TTL based on response status overrides the default cache behavior (standard caching) for static files and overrides cache instructions sent by the origin web server. To cache non-static assets, set a Cache Level of Cache Everything using a Page Rule. Setting no-store Cache-Control or a low TTL (using max-age/s-maxage) increases requests to origin web servers and decreases performance.                                                                                                           | Enterprise              |
| [Custom Cache Key](https://developers.cloudflare.com/cache/how-to/cache-keys/)                                                   | Control specifically what variables to include when deciding which resources to cache. This allows customers to determine what to cache based on something other than just the URL.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Enterprise              |
| Disable Zaraz                                                                                                                    | Turn off [Zaraz](https://developers.cloudflare.com/zaraz/).NoteTo use this feature on specific hostnames - instead of across your entire zone - use a [configuration rule](https://developers.cloudflare.com/rules/configuration-rules/).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | All                     |
| Edge Cache TTL                                                                                                                   | Specify how long to cache a resource in the Cloudflare global network. _Edge Cache TTL_ is not visible in response headers.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | All                     |
| [Email Obfuscation](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/)                        | Turn on or off **Email Obfuscation**.NoteTo use this feature on specific hostnames - instead of across your entire zone - use a [configuration rule](https://developers.cloudflare.com/rules/configuration-rules/).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | All                     |
| Forwarding URL                                                                                                                   | Redirects one URL to another using an HTTP 301/302 redirect. Refer to [Wildcard matching in Page Rules](https://developers.cloudflare.com/rules/page-rules/reference/wildcard-matching/).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | All                     |
| Host Header Override                                                                                                             | Apply a specific host header.NoteYou can accomplish the same effect with an [origin rule](https://developers.cloudflare.com/rules/origin-rules/features/#host-header).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Enterprise              |
| IP Geolocation Header                                                                                                            | Cloudflare adds a CF-IPCountry HTTP header containing the country code that corresponds to the visitor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | All                     |
| [Opportunistic Encryption](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/opportunistic-encryption/) | Turn on or off the **Opportunistic Encryption**.NoteTo use this feature on specific hostnames - instead of across your entire zone - use a [configuration rule](https://developers.cloudflare.com/rules/configuration-rules/).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | All                     |
| [Origin Cache Control](https://developers.cloudflare.com/cache/concepts/cache-control/)                                          | Origin Cache Control is enabled by default for Free, Pro, and Business domains and disabled by default for Enterprise domains.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | All                     |
| Origin Error Page Pass-thru                                                                                                      | Turn on or off Cloudflare error pages generated from issues sent from the origin server. If enabled, this setting triggers error pages issued by the origin.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                | Enterprise              |
| [Polish](https://developers.cloudflare.com/images/polish/)                                                                       | Apply options from the **Polish** feature of the Cloudflare **Speed** app.NoteTo use this feature on specific hostnames - instead of across your entire zone - use a [configuration rule](https://developers.cloudflare.com/rules/configuration-rules/).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | Pro and above           |
| [Query String Sort](https://developers.cloudflare.com/cache/advanced-configuration/query-string-sort/)                           | Turn on or off the reordering of query strings. When query strings have the same structure, caching improves.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               | Enterprise              |
| Resolve Override                                                                                                                 | Change the origin address to the value specified in this setting. NoteYou can accomplish the same effect with an [origin rule](https://developers.cloudflare.com/rules/origin-rules/features/#dns-record).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Enterprise              |
| [Respect Strong ETags](https://developers.cloudflare.com/cache/reference/etag-headers/)                                          | Turn on or off byte-for-byte equivalency checks between the Cloudflare cache and the origin server.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         | Enterprise              |
| Response Buffering                                                                                                               | Turn on or off whether Cloudflare should wait for an entire file from the origin server before forwarding it to the site visitor. By default, Cloudflare sends packets to the client as they arrive from the origin server.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | Enterprise              |
| [Rocket Loader](https://developers.cloudflare.com/speed/optimization/content/rocket-loader/)                                     | Turn on or off **Rocket Loader** in the Cloudflare **Speed** app.NoteTo use this feature on specific hostnames - instead of across your entire zone - use a [configuration rule](https://developers.cloudflare.com/rules/configuration-rules/).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             | All                     |
| [SSL](https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/)                                                     | Control options for the **SSL** feature of the **Edge Certificates** tab in the Cloudflare **SSL/TLS** app.NoteTo use this feature on specific hostnames - instead of across your entire zone - use a [configuration rule](https://developers.cloudflare.com/rules/configuration-rules/).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | All                     |
| True Client IP Header                                                                                                            | Turn on or off the [**True-Client-IP Header**](https://developers.cloudflare.com/network/true-client-ip-header/) feature of the Cloudflare **Network** app.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | Enterprise              |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/page-rules/","name":"Page Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/page-rules/reference/","name":"Reference"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/page-rules/reference/settings/","name":"Page Rules settings"}}]}
```

---

---
title: Wildcard matching in Page Rules
description: You can use the asterisk (*) in any URL segment to match certain patterns. For example, example.com/t*st would match:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/page-rules/reference/wildcard-matching.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Wildcard matching in Page Rules

You can use the asterisk (`*`) in any URL segment to match certain patterns. For example, `example.com/t*st` would match:

* `example.com/test`
* `example.com/toast`
* `example.com/trust`

`example.com/foo/* `does not match `example.com/foo`, but `example.com/foo*` does match.

Note

Consider alternative [Rules](https://developers.cloudflare.com/rules/) options due to their enhanced configurability. Refer to the [migration guide](https://developers.cloudflare.com/rules/reference/page-rules-migration/) for details.

For more flexibility and customization, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

## Helpful tips

* To match both `http` and `https`, write `example.com`. Writing `*example.com` is unnecessary.
* To match every page on a domain, write `example.com/*`. Writing `example.com` will not work.
* To match every page on a domain and its subdomains, write `*example.com/*`. Writing `example.com` will not work.
* A wildcard (`*`) in a page rule URL will match even if no characters are present and may include any part of the URL, including the query string.

## Reference wildcard matches

You can reference a matched wildcard later using the `$<X>` syntax, where `<X>` indicates the index of a glob pattern. For example, `$1` represents the first wildcard match and `$2` represents the second wildcard match.

The `$<X>` syntax is especially useful with the _Forwarding URL_ setting. For example, you could forward `http://*.example.com/*` to `http://example.com/images/$1/$2.jpg`.

This rule would match `http://cloud.example.com/flare.jpg`, which would be forwarded to `http://example.com/images/cloud/flare.jpg`.

To add a `$` character in the forwarding URL, escape it by adding a backslash `\` in front like `\$`.

Warning

Avoid creating a redirect where the domain points to itself as the destination. A domain that points to itself can cause an [infinite redirect error](https://developers.cloudflare.com/ssl/troubleshooting/too-many-redirects/), which makes your site inaccessible to visitors.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/page-rules/","name":"Page Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/page-rules/reference/","name":"Reference"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/page-rules/reference/wildcard-matching/","name":"Wildcard matching in Page Rules"}}]}
```

---

---
title: Troubleshoot Page Rules - Billing and subscription
description: No, you cannot buy additional Page Rules. You will need to migrate to modern Rules features to benefit from increased quotas.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/page-rules/troubleshooting/billing-and-subscription.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Troubleshoot Page Rules - Billing and subscription

Note

Consider alternative [Rules](https://developers.cloudflare.com/rules/) options due to their enhanced configurability. Refer to the [migration guide](https://developers.cloudflare.com/rules/reference/page-rules-migration/) for details.

For more flexibility and customization, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

## If I run out of Page Rules, can I buy more?

No, you cannot buy additional Page Rules. You will need to [migrate to modern Rules features](https://developers.cloudflare.com/rules/reference/page-rules-migration/) to benefit from increased quotas.

## How do I cancel my Page Rules purchase?

To cancel a purchase:

1. In the Cloudflare dashboard, go to the **Billing** page.  
[ Go to **Billing** ](https://dash.cloudflare.com/?to=/:account/billing)
2. Go to **Subscriptions**.
3. Find the associated website (listed in alphabetical order) and select **Edit**.
4. For **Additional page rules**, change the amount to your previous value. If you are over your current limit, you may have to delete existing page rules (paused or active).
5. Finish the updates to your subscription.

## When I change plans will I keep my add-on subscriptions?

When you change plans, you will keep your Page Rules add-on subscription.

## What happens if I cancel Page Rules halfway through my billing cycle?

You will be billed for and have access to your additional Page Rules until the end of your current billing cycle.

Your plan will adjust at the start of your next billing cycle. For more details, refer to our [billing policy](https://developers.cloudflare.com/billing/billing-policy/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/page-rules/","name":"Page Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/page-rules/troubleshooting/","name":"Troubleshooting"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/page-rules/troubleshooting/billing-and-subscription/","name":"Troubleshoot Page Rules - Billing and subscription"}}]}
```

---

---
title: Troubleshoot Page Rules - General
description: The most common reason that a page rule is not working — such as URL forwarding — is that the page rule you created is on a record that is not proxied by Cloudflare in your DNS settings.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/page-rules/troubleshooting/general.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Troubleshoot Page Rules - General

Note

Consider alternative [Rules](https://developers.cloudflare.com/rules/) options due to their enhanced configurability. Refer to the [migration guide](https://developers.cloudflare.com/rules/reference/page-rules-migration/) for details.

For more flexibility and customization, consider using [Snippets](https://developers.cloudflare.com/rules/snippets/).

## Why is a page rule not working?

The most common reason that a page rule is not working — such as URL forwarding — is that the page rule you created is on a record that is not proxied by Cloudflare in your [DNS settings](https://developers.cloudflare.com/dns/manage-dns-records/how-to/create-dns-records/).

Consider an example where you have a page rule that redirects a subdomain (`subdomain.yoursitename.com`) back to your apex domain (`yoursitename.com`). If you do not have that record proxied in your DNS settings for the subdomain record, Cloudflare's proxy is not running over the record and a page rule will not work because it is going direct to your server.

## Error 500 (Internal server error)

### Root cause

This may be due to a configuration issue on a page rule. When creating a page rule that uses two wildcards, like a _Forwarding URL_ rule, it is possible to create a rule that mentions the second wildcard with the `$2` placeholder. Refer to the example below:

![Example Page Rule configuration with two wildcards. The forwarding URL contains a $2 placeholder, which will be replaced with the content matched by the second ](https://developers.cloudflare.com/_astro/page-rule-create.G2sl-mqe_wuqS2.webp) 

When updating the same rule, you can remove one of the wildcard in the **If the URL matches** field and save it. Refer to the example below:

![Incorrect Page Rule configuration with a single wildcard, but still using the $2 placeholder in the forwarding URL. This configuration causes ](https://developers.cloudflare.com/_astro/page-rule-update.C2mx06CJ_Z1ECvOK.webp) 

If you do so, the `$2` placeholder reference a wildcard that does not exist anymore, and as such, an `Error 500 (Internal server error)` is thrown when a URL triggers the page rule.

### Resolution

Update the page rule and remove the reference `$2` to the second wildcard. If there is only one wildcard, then you can only use `$1`.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/page-rules/","name":"Page Rules"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/page-rules/troubleshooting/","name":"Troubleshooting"}},{"@type":"ListItem","position":5,"item":{"@id":"/rules/page-rules/troubleshooting/general/","name":"Troubleshoot Page Rules - General"}}]}
```

---

---
title: URL normalization
description: Cloudflare provides a URL normalization feature to modify the URLs of incoming requests so that they conform to a consistent formatting standard.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/normalization/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# URL normalization

Cloudflare provides a URL normalization feature to modify the URLs of incoming requests so that they conform to a consistent formatting standard.

When you enable URL normalization, all incoming URLs are normalized before they pass to subsequent global network features that accept a URL input, such as WAF custom rules, Workers, and Access. Rule expressions that filter traffic based on URLs will therefore trigger correctly, regardless of the format of the incoming URL. When URL normalization is disabled, Cloudflare forwards the URL to origin in its original form.

Warning

When traffic is proxied via Cloudflare, essential request URL normalization is always applied regardless whether URL normalization is enabled for a specific zone. For example, you cannot disable the conversion of two or more adjacent slashes into a single slash in a request URL by turning off URL normalization.

URL normalization does not perform any redirects, and therefore it will not change the address displayed in the visitor's browser. The normalization operation, when enabled, occurs on the global network and affects Cloudflare features executed later and (optionally) the URL received at the origin server.

Note

URL normalization requires that you [proxy the DNS records](https://developers.cloudflare.com/dns/proxy-status/) of your domain (or subdomain) through Cloudflare.

---

## Availability

URL normalization is available in all Cloudflare plans.

## Get started

Learn more about [URL normalization](https://developers.cloudflare.com/rules/normalization/how-it-works/) and how to [configure URL normalization](https://developers.cloudflare.com/rules/normalization/manage/) in the Cloudflare dashboard.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/normalization/","name":"URL normalization"}}]}
```

---

---
title: URL normalization examples
description: Examples of the impact of different URL normalization settings in the URLs of incoming requests.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Copy page

# URL normalization examples

The following table shows how different [URL normalization settings](https://developers.cloudflare.com/rules/normalization/settings/) affect request URLs before they pass to other Cloudflare features and to the origin server:

| Incoming URL                | Normalization type | Normalize incoming URLs | Normalize URLs to origin | URL at Cloudflare's network  | URL passed to origin server  |
| --------------------------- | ------------------ | ----------------------- | ------------------------ | ---------------------------- | ---------------------------- |
| www.example.com/hello       | (any)              | _Off_                   | _Off_                    | www.example.com/hello        | www.example.com/hello        |
| www.example.com/hello       | (any)              | _On_                    | _Off_                    | www.example.com/hello        | www.example.com/hello        |
| www.example.com/hello       | (any)              | _On_                    | _On_                     | www.example.com/hello        | www.example.com/hello        |
| example.com/%68ello         | (any)              | _Off_                   | _Off_                    | example.com/%68ello          | example.com/%68ello          |
| example.com/%68ello         | (any)              | _On_                    | _Off_                    | example.com/hello            | example.com/%68ello          |
| example.com/%68ello         | (any)              | _On_                    | _On_                     | example.com/hello            | example.com/hello            |
| example.com/%68ello//pa\\th | _RFC-3986_         | _Off_                   | _Off_                    | example.com/%68ello//pa\\th  | example.com/%68ello//pa\\th  |
| example.com/%68ello//pa\\th | _RFC-3986_         | _On_                    | _Off_                    | example.com/hello//pa%5Cth   | example.com/%68ello//pa\\th  |
| example.com/%68ello//pa\\th | _RFC-3986_         | _On_                    | _On_                     | example.com/hello//pa%5Cth   | example.com/hello//pa%5Cth   |
| example.com/%68ello//pa\\th | _Cloudflare_       | _Off_                   | _Off_                    | example.com/%68ello//pa\\th  | example.com/%68ello//pa\\th  |
| example.com/%68ello//pa\\th | _Cloudflare_       | _On_                    | _Off_                    | example.com/hello/pa/th      | example.com/%68ello//pa\\th  |
| example.com/%68ello//pa\\th | _Cloudflare_       | _On_                    | _On_                     | example.com/hello/pa/th      | example.com/hello/pa/th      |
| example.com/hello//../path  | _RFC-3986_         | _On_                    | _On_                     | example.com/hello/path       | example.com/hello/path       |
| example.com/hello//../path  | _Cloudflare_       | _On_                    | _On_                     | example.com/path             | example.com/path             |
| example.com/hello/\\../path | _RFC-3986_         | _On_                    | _On_                     | example.com/hello/%5C../path | example.com/hello/%5C../path |
| example.com/hello/\\../path | _Cloudflare_       | _On_                    | _On_                     | example.com/path             | example.com/path             |

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/normalization/","name":"URL normalization"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/normalization/examples/","name":"URL normalization examples"}}]}
```

---

---
title: How URL normalization works
description: URL normalization modifies separators, encoded elements, and literal bytes in incoming URLs so that they conform to a consistent formatting standard.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/normalization/how-it-works.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# How URL normalization works

URL normalization modifies separators, encoded elements, and literal bytes in incoming URLs so that they conform to a consistent formatting standard.

For example, consider a WAF custom rule that blocks requests whose URLs match `www.example.com/hello`. The rule would not block a request containing an encoded element — `www.example.com/%68ello`. Normalizing incoming URLs on the Cloudflare global network helps simplify rules expressions containing URLs.

The two available types of URL normalization are:

* [RFC 3986 normalization](#rfc-3986-normalization)
* [Cloudflare normalization](#cloudflare-normalization)

The location where URL normalization will occur depends on the [configured settings](https://developers.cloudflare.com/rules/normalization/settings/).

For examples of the different settings and their impact on request URLs, refer to the [URL normalization examples](https://developers.cloudflare.com/rules/normalization/examples/).

## RFC 3986 normalization

The URL normalization performed according to [RFC 3986 ↗](https://www.ietf.org/rfc/rfc3986.txt) is as follows:

* The following unreserved characters are [percent decoded ↗](https://tools.ietf.org/html/rfc3986#section-2.1):  
   * Alphabetical characters: `a`\-`z`, `A`\-`Z` (decoded from `%41`\-`%5A` and `%61`\-`%7A`)  
   * Digit characters: `0`\-`9` (decoded from `%30`\-`%39`)  
   * hyphen `-` (`%2D`), period `.` (`%2E`), underscore `_` (`%5F`), and tilde `~` (`%7E`)
* These reserved characters are not encoded or decoded: `: / ? # [ ] @ ! $ & ' ( ) * + , ; =`
* Other characters, for example literal byte values, are percent encoded.
* Percent encoded representations are converted to upper case.
* URL paths are normalized according to the [Remove Dot Segments ↗](https://tools.ietf.org/html/rfc3986#section-5.2.4) protocol.

## Cloudflare normalization

When using the Cloudflare URL normalization, some extra normalization techniques will be applied to URLs of incoming requests, in the following order:

1. Normalize back slashes (`\`) into forward slashes (`/`).
2. Merge successive forward slashes (for example, `//` will be normalized to `/`).
3. Perform [RFC 3986 normalization](#rfc-3986-normalization) of the resulting URL.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/normalization/","name":"URL normalization"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/normalization/how-it-works/","name":"How URL normalization works"}}]}
```

---

---
title: Configure URL normalization in the dashboard
description: How to configure URL normalization in the Cloudflare dashboard.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/normalization/manage.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Configure URL normalization in the dashboard

1. In the Cloudflare dashboard, go to the Rules **Settings** page.  
[ Go to **Settings** ](https://dash.cloudflare.com/?to=/:account/:zone/rules/settings)
2. Go to the **URL Normalization** tab.
3. Configure the [available URL normalization settings](https://developers.cloudflare.com/rules/normalization/settings/).  
![Available URL normalization settings in the Cloudflare dashboard](https://developers.cloudflare.com/_astro/url-normalization-settings.CiswBm53_Z1XMaUF.webp)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/normalization/","name":"URL normalization"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/normalization/manage/","name":"Configure URL normalization in the dashboard"}}]}
```

---

---
title: URL normalization settings
description: The Cloudflare dashboard provides the following settings to manage URL normalization:
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/normalization/settings.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# URL normalization settings

The Cloudflare dashboard provides the following settings to manage URL normalization:

## Normalization type

Default value: _RFC-3986_

Selects the type of normalization to perform:

* _RFC-3986_ – Applies URL normalization strictly according to [RFC 3986 ↗](https://datatracker.ietf.org/doc/html/rfc3986).
* _Cloudflare_ – In addition to what is defined in RFC 3986, applies [extra URL normalization techniques](https://developers.cloudflare.com/rules/normalization/how-it-works/#cloudflare-normalization).

## Normalize incoming URLs

Default value: _On_

Configures the URLs of all incoming traffic to Cloudflare:

* When enabled, all incoming URLs are normalized before they pass to subsequent Cloudflare features that can receive a URL as input, such as Page Rules, WAF custom rules, Workers, and Access.
* When disabled, incoming URLs are not normalized before passing to subsequent Cloudflare features.

## Normalize URLs to origin

Default value: _Off_

Configures URLs sent to the origin:

* When enabled, requests sent to the origin are normalized.
* When disabled, requests sent to the origin are not modified.

You can only view and enable this option when **Normalize incoming URLs** is enabled.

For examples of how these settings affect URL normalization, refer to the [URL normalization examples](https://developers.cloudflare.com/rules/normalization/examples/).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/normalization/","name":"URL normalization"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/normalization/settings/","name":"URL normalization settings"}}]}
```

---

---
title: Trace a request
description: Cloudflare Trace (Beta) follows an HTTP/S request through Cloudflare's reverse proxy to your origin. Use this tool to understand how different Cloudflare configurations interact with an HTTP/S request for one of your hostnames. If the hostname you are testing is not proxied by Cloudflare, Cloudflare Trace will still return all the configurations that Cloudflare would have applied to the request.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/trace-request/index.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Trace a request

 Available on all plans 

Cloudflare Trace (Beta) follows an HTTP/S request through Cloudflare's reverse proxy to your origin. Use this tool to understand how different Cloudflare configurations interact with an HTTP/S request for one of your hostnames. If the hostname you are testing is not [proxied by Cloudflare](https://developers.cloudflare.com/dns/proxy-status/), Cloudflare Trace will still return all the configurations that Cloudflare would have applied to the request.

You can define specific request properties to simulate different conditions for an HTTP/S request. Inactive rules configured in Cloudflare products will not be evaluated.

Cloudflare Trace is available to users with an Administrator or Super Administrator role.

## When to use Trace

Use Trace when you need to test what would happen with a simulated request:

* Understanding why a rule did not trigger as expected
* Testing how your rules handle different request scenarios
* Seeing the evaluation order of your rules
* Simulating requests from different geolocations or conditions

Use [Log Explorer](https://developers.cloudflare.com/log-explorer/) when you need to investigate what actually happened with real production traffic:

* Analyzing historical data and trends
* Investigating security incidents after they occur
* Searching for patterns across thousands of requests
* Monitoring application performance over time
* Providing forensic evidence to support teams

The key difference is that Trace simulates "what-if" scenarios, while Log Explorer shows actual historical traffic.

## Resources

* [ Use Cloudflare Trace ](https://developers.cloudflare.com/rules/trace-request/how-to/)
* [ Cloudflare Trace limitations ](https://developers.cloudflare.com/rules/trace-request/limitations/)
* [ Cloudflare Trace changelog ](https://developers.cloudflare.com/rules/trace-request/changelog/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/trace-request/","name":"Trace a request"}}]}
```

---

---
title: Cloudflare Trace changelog
description: Subscribe to RSS
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/trace-request/changelog.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cloudflare Trace changelog

[ Subscribe to RSS ](https://developers.cloudflare.com/rules/trace-request/changelog/index.xml)

## 2024-04-15

**Cloudflare Trace now supports Workers**

Starting today, customers can use Cloudflare Trace to confirm if a request to a specific URL within their zone is routed through a [Workers script](https://developers.cloudflare.com/workers/).

## 2024-03-18

**Cloudflare Trace now supports BYOIP zones**

Customers can now use Cloudflare Trace to trace HTTP/S requests through their [BYOIP](https://developers.cloudflare.com/byoip/) zones.

## 2024-03-12

**Cloudflare Trace now supports grey-clouded hostnames**

Even if the hostname is [not proxied by Cloudflare](https://developers.cloudflare.com/dns/proxy-status/#dns-only-records), Cloudflare Trace will now return all the configurations that Cloudflare would have applied to the request.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/trace-request/","name":"Trace a request"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/trace-request/changelog/","name":"Cloudflare Trace changelog"}}]}
```

---

---
title: Use Cloudflare Trace
description: Learn how to use Cloudflare Trace in the dashboard and with the API.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/trace-request/how-to.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Use Cloudflare Trace

## Use Trace in the dashboard

### 1\. Configure one or more Cloudflare products

1. Log in to the [Cloudflare dashboard ↗](https://dash.cloudflare.com), and select your account.
2. Set configuration settings at the account level, or select a domain and configure settings for one or more Cloudflare products.

### 2\. Build a trace

1. In the Cloudflare dashboard, go to the **Trace** page.  
[ Go to **Trace** ](https://dash.cloudflare.com/?to=/:account/trace)
2. Enter a URL to trace. The URL must include a hostname that belongs to your account.
3. Select an HTTP method. If you select _POST_, _PUT_, or _PATCH_, you should enter a value in **Request Body**.
4. (Optional) Define any custom request properties to simulate the conditions of a specific HTTP/S request. You can customize the following request properties:  
   * **Protocol** (HTTP protocol version)  
   * **User Agent and Request Headers**  
   * **Cookies**  
   * **Geolocation** (request source [country](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.country/), [region](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.region/), and [city](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.city/))  
   * [**Bot Score**](https://developers.cloudflare.com/bots/concepts/bot-score/)  
   * **Request Body** (for `POST`, `PUT`, and `PATCH` requests)  
   * **Skip Challenge** (skips a Cloudflare-issued [challenge](https://developers.cloudflare.com/cloudflare-challenges/), if any, allowing the trace to continue)
5. Select **Send Trace**.

### 3\. Assess results

The **Trace results** page shows all evaluated and executed configurations from different Cloudflare products, in evaluation order. Any inactive rules are not evaluated.

1. Analyze the different [steps](#steps-in-trace-results) with evaluated and executed configurations for the current trace. Trace results include matches for all active rules and configurations, whether configured at the account level or for a specific domain or subdomain.  
To show all configurations, including the ones that did not match the request, select _All configurations_ in the **Results shown** dropdown.
2. (Optional) Update your Cloudflare configuration (at the account or at the domain/subdomain level) and create a new trace to check the impact of your changes.

### 4\. (Optional) Save the trace configuration

To run a trace later with the same configuration:

1. Copy the JSON shown in the dashboard with the current trace configuration.
2. When creating a new trace, paste it in the JSON box to define all the settings of the new trace.

## Use Trace via API

Use the [Request Trace](https://developers.cloudflare.com/api/resources/request%5Ftracers/subresources/traces/methods/create/) operation to perform a trace using the Cloudflare API.

---

## Steps in trace results

* Execution of one or more rules of Cloudflare products built on the [Ruleset Engine](https://developers.cloudflare.com/ruleset-engine/). Refer to the Ruleset Engine's [Phases list](https://developers.cloudflare.com/ruleset-engine/reference/phases-list/) for a list of such products.
* [Page Rules](https://developers.cloudflare.com/rules/page-rules/): Execution of one or more rules.
* [Workers](https://developers.cloudflare.com/workers/): Execution of one or more scripts.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/trace-request/","name":"Trace a request"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/trace-request/how-to/","name":"Use Cloudflare Trace"}}]}
```

---

---
title: Cloudflare Trace limitations
description: Trace does not display rules that are automatically bypassed for operational reasons.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/trace-request/limitations.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Cloudflare Trace limitations

## Automatic rule bypasses

Trace does not display rules that are automatically bypassed for operational reasons.

For example, when SSL/TLS certificates are in `pending_validation` status, security rules are automatically disabled for domain control validation (DCV) paths like `/.well-known/pki-validation/` and `/.well-known/acme-challenge/`. These bypasses will not appear in trace results.

For more information, refer to [Why are some rules bypassed?](https://developers.cloudflare.com/waf/troubleshooting/faq/#why-are-some-rules-bypassed-when-i-did-not-create-an-exception) in the WAF documentation.

---

## Unsupported features

Trace currently does not support:

* Hostnames using [Data Localization Suite](https://developers.cloudflare.com/data-localization/)
* [Spectrum](https://developers.cloudflare.com/spectrum/) applications

Additionally, the following products will not appear in trace results:

* [Firewall rules (deprecated)](https://developers.cloudflare.com/firewall/)
* [Load Balancing](https://developers.cloudflare.com/load-balancing/) and [Load Balancer Custom Rules](https://developers.cloudflare.com/load-balancing/additional-options/load-balancing-rules/)
* [IP Access rules](https://developers.cloudflare.com/waf/tools/ip-access-rules/)
* [Rate limiting rules (previous version)](https://developers.cloudflare.com/waf/reference/legacy/old-rate-limiting/)
* [WAF managed rules (previous version)](https://developers.cloudflare.com/waf/reference/legacy/old-waf-managed-rules/)
* [Content security rules](https://developers.cloudflare.com/client-side-security/rules/)

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/trace-request/","name":"Trace a request"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/trace-request/limitations/","name":"Cloudflare Trace limitations"}}]}
```

---

---
title: Rules changelog
description: Two new fields are now available in rule expressions that surface Layer 4 transport telemetry from the client connection. Together with the existing cf.timings.client_tcp_rtt_msec field, these fields give you a complete picture of connection quality for both TCP and QUIC traffic — enabling transport-aware rules without requiring any client-side changes.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/changelog.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Rules changelog

[ Subscribe to RSS ](https://developers.cloudflare.com/changelog/rss/rules.xml) 

## 2026-04-01

  
**New QUIC RTT and delivery rate fields**   

Two new fields are now available in rule expressions that surface Layer 4 transport telemetry from the client connection. Together with the existing [cf.timings.client\_tcp\_rtt\_msec](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/) field, these fields give you a complete picture of connection quality for both TCP and QUIC traffic — enabling transport-aware rules without requiring any client-side changes.

Previously, QUIC RTT and delivery rate data was only available via the `Server-Timing: cfL4` response header. These new fields make the same data available directly in rule expressions, so you can use them in Transform Rules, WAF Custom Rules, and other phases that support dynamic fields.

#### New fields

| Field                              | Type    | Description                                                                                                                                                             |
| ---------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| cf.timings.client\_quic\_rtt\_msec | Integer | The smoothed QUIC round-trip time (RTT) between Cloudflare and the client in milliseconds. Only populated for QUIC (HTTP/3) connections. Returns 0 for TCP connections. |
| cf.edge.l4.delivery\_rate          | Integer | The most recent data delivery rate estimate for the client connection, in bytes per second. Returns 0 when L4 statistics are not available for the request.             |

#### Example: Route slow connections to a lightweight origin

Use a request header transform rule to tag requests from high-latency connections, so your origin can serve a lighter page variant:

**Rule expression:**

```

cf.timings.client_tcp_rtt_msec > 200 or cf.timings.client_quic_rtt_msec > 200


```

**Header modifications:**

| Operation | Header name    | Value |
| --------- | -------------- | ----- |
| Set       | X-High-Latency | true  |

#### Example: Match low-bandwidth connections

```

cf.edge.l4.delivery_rate > 0 and cf.edge.l4.delivery_rate < 100000


```

For more information, refer to [Request Header Transform Rules](https://developers.cloudflare.com/rules/transform/request-header-modification/) and the [fields reference](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/).

## 2026-03-25

  
**New mTLS certificate fields for Transform Rules**   

Cloudflare now exposes four new fields in the Transform Rules phase that encode client certificate data in [RFC 9440 ↗](https://www.rfc-editor.org/rfc/rfc9440) format. Previously, forwarding client certificate information to your origin required custom parsing of PEM-encoded fields or non-standard HTTP header formats. These new fields produce output in the standardized `Client-Cert` and `Client-Cert-Chain` header format defined by RFC 9440, so your origin can consume them directly without any additional decoding logic.

Each certificate is DER-encoded, Base64-encoded, and wrapped in colons. For example, `:MIIDsT...Vw==:`. A chain of intermediates is expressed as a comma-separated list of such values.

#### New fields

| Field                                                 | Type    | Description                                                                                                                                                      |
| ----------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| cf.tls\_client\_auth.cert\_rfc9440                    | String  | The client leaf certificate in RFC 9440 format. Empty if no client certificate was presented.                                                                    |
| cf.tls\_client\_auth.cert\_rfc9440\_too\_large        | Boolean | true if the leaf certificate exceeded 10 KB and was omitted. In practice this will almost always be false.                                                       |
| cf.tls\_client\_auth.cert\_chain\_rfc9440             | String  | The intermediate certificate chain in RFC 9440 format as a comma-separated list. Empty if no intermediate certificates were sent or if the chain exceeded 16 KB. |
| cf.tls\_client\_auth.cert\_chain\_rfc9440\_too\_large | Boolean | true if the intermediate chain exceeded 16 KB and was omitted.                                                                                                   |

The chain encoding follows the same ordering as the TLS handshake: the certificate closest to the leaf appears first, working up toward the trust anchor. The root certificate is not included.

#### Example: Forwarding client certificate headers to your origin server

Add a request header transform rule to set the `Client-Cert` and `Client-Cert-Chain` headers on requests forwarded to your origin server. For example, to forward headers for verified, non-revoked certificates:

**Rule expression:**

```

cf.tls_client_auth.cert_verified and not cf.tls_client_auth.cert_revoked


```

**Header modifications:**

| Operation | Header name       | Value                                     |
| --------- | ----------------- | ----------------------------------------- |
| Set       | Client-Cert       | cf.tls\_client\_auth.cert\_rfc9440        |
| Set       | Client-Cert-Chain | cf.tls\_client\_auth.cert\_chain\_rfc9440 |

To get the most out of these fields, upload your client CA certificate to Cloudflare so that Cloudflare validates the client certificate at the edge and populates `cf.tls_client_auth.cert_verified` and `cf.tls_client_auth.cert_revoked`.

Prevent header injection

You should ensure that `Client-Cert` and `Client-Cert-Chain` headers received by your origin server can only originate from this transform rule — any client could send these headers directly.

* **If you use WAF custom rules to block requests with invalid mTLS connections:** The transform rule is sufficient. For all requests that reach your origin server, the rule will overwrite any existing `Client-Cert` and `Client-Cert-Chain` headers.
* **If you do not enforce mTLS at the WAF:** Add another transform rule that removes any incoming `Client-Cert` and `Client-Cert-Chain` headers from all requests (use expression `true`), ordered before the rule above. This ensures your origin server cannot receive client-supplied values for these HTTP headers.

For more information, refer to [Mutual TLS authentication](https://developers.cloudflare.com/cloudflare-one/access-controls/service-credentials/mutual-tls-authentication/), [Request Header Transform Rules](https://developers.cloudflare.com/rules/transform/request-header-modification/), and the [fields reference](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/).

## 2026-03-18

  
**Worker execution timing field now available in Rules**   

The `cf.timings.worker_msec` field is now available in the Ruleset Engine. This field reports the wall-clock time that a Cloudflare Worker spent handling a request, measured in milliseconds.

You can use this field to identify slow Worker executions, detect performance regressions, or build rules that respond differently based on Worker processing time, such as logging requests that exceed a latency threshold.

#### Field details

| Field                   | Type    | Description                                                                                       |
| ----------------------- | ------- | ------------------------------------------------------------------------------------------------- |
| cf.timings.worker\_msec | Integer | The time spent executing a Cloudflare Worker in milliseconds. Returns 0 if no Worker was invoked. |

Example filter expression:

```

cf.timings.worker_msec > 500


```

For more information, refer to the [Fields reference](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.timings.worker%5Fmsec/).

## 2026-01-27

  
**Control request and response body buffering in Configuration Rules**   

You can now control how Cloudflare buffers HTTP request and response bodies using two new settings in [Configuration Rules](https://developers.cloudflare.com/rules/configuration-rules/).

#### Request body buffering

Controls how Cloudflare buffers HTTP request bodies before forwarding them to your origin server:

| Mode                   | Behavior                                                                                                      |
| ---------------------- | ------------------------------------------------------------------------------------------------------------- |
| **Standard** (default) | Cloudflare can inspect a prefix of the request body for enabled functionality such as WAF and Bot Management. |
| **Full**               | Buffers the entire request body before sending to origin.                                                     |
| **None**               | No buffering — the request body streams directly to origin without inspection.                                |

#### Response body buffering

Controls how Cloudflare buffers HTTP response bodies before forwarding them to the client:

| Mode                   | Behavior                                                                            |
| ---------------------- | ----------------------------------------------------------------------------------- |
| **Standard** (default) | Cloudflare can inspect a prefix of the response body for enabled functionality.     |
| **None**               | No buffering — the response body streams directly to the client without inspection. |

Warning

Setting body buffering to **None** may break security functionality that requires body inspection, including the Web Application Firewall (WAF) and Bot Management. Ensure that any paths where you disable buffering do not require security inspection.

Availability

These settings only take effect on zones running Cloudflare's [latest CDN proxy ↗](https://blog.cloudflare.com/20-percent-internet-upgrade/). Enterprise customers can contact their account team to enable the latest proxy on their zones.

#### API example

```

{

  "action": "set_config",

  "action_parameters": {

    "request_body_buffering": "standard",

    "response_body_buffering": "none"

  }

}


```

For more information, refer to [Configuration Rules](https://developers.cloudflare.com/rules/configuration-rules/).

## 2026-01-22

  
**New cryptographic functions — encode\_base64() and sha256()**   

Cloudflare Rulesets now includes `encode_base64()` and `sha256()` functions, enabling you to generate signed request headers directly in rule expressions. These functions support common patterns like constructing a canonical string from request attributes, computing a SHA256 digest, and Base64-encoding the result.

---

#### New functions

| Function                     | Description                                                                                                                                                                                                                                             | Availability                          |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- |
| encode\_base64(input, flags) | Encodes a string to Base64 format. Optional flags parameter: u for URL-safe encoding, p for padding (adds \= characters to make the output length a multiple of 4, as required by some systems). By default, output is standard Base64 without padding. | All plans (in header transform rules) |
| sha256(input)                | Computes a SHA256 hash of the input string.                                                                                                                                                                                                             | Requires enablement                   |

Note

The `sha256()` function is available as an Enterprise add-on and requires a specific entitlement. Contact your account team to enable it.

---

#### Examples

**Encode a string to Base64 format:**

```

encode_base64("hello world")


```

Returns: `aGVsbG8gd29ybGQ`

**Encode a string to Base64 format with padding:**

```

encode_base64("hello world", "p")


```

Returns: `aGVsbG8gd29ybGQ=`

**Perform a URL-safe Base64 encoding of a string:**

```

encode_base64("hello world", "u")


```

Returns: `aGVsbG8gd29ybGQ`

**Compute the SHA256 hash of a secret token:**

```

sha256("my-token")


```

Returns a hash that your origin can validate to authenticate requests.

**Compute the SHA256 hash of a string and encode the result to Base64 format:**

```

encode_base64(sha256("my-token"))


```

Combines hashing and encoding for systems that expect Base64-encoded signatures.

For more information, refer to the [Functions reference](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/).

## 2026-01-20

  
**New functions for array and map operations**   

#### New functions for array and map operations

Cloudflare Rulesets now include new functions that enable advanced expression logic for evaluating arrays and maps. These functions allow you to build rules that match against lists of values in request or response headers, enabling use cases like country-based blocking using custom headers.

---

#### New functions

| Function                 | Description                                                                   |
| ------------------------ | ----------------------------------------------------------------------------- |
| split(source, delimiter) | Splits a string into an array of strings using the specified delimiter.       |
| join(array, delimiter)   | Joins an array of strings into a single string using the specified delimiter. |
| has\_key(map, key)       | Returns true if the specified key exists in the map.                          |
| has\_value(map, value)   | Returns true if the specified value exists in the map.                        |

---

#### Example use cases

**Check if a country code exists in a header list:**

```

has_value(split(http.response.headers["x-allow-country"][0], ","), ip.src.country)


```

**Check if a specific header key exists:**

```

has_key(http.request.headers, "x-custom-header")


```

**Join array values for logging or comparison:**

```

join(http.request.headers.names, ", ")


```

For more information, refer to the [Functions reference](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/).

## 2026-01-12

  
**Metro code field now available in Rules**   

The `ip.src.metro_code` field in the Ruleset Engine is now populated with DMA (Designated Market Area) data.

You can use this field to build rules that target traffic based on geographic market areas, enabling more granular location-based policies for your applications.

#### Field details

| Field              | Type           | Description                                                                                                                   |
| ------------------ | -------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| ip.src.metro\_code | String \| null | The metro code (DMA) of the incoming request's IP address. Returns the designated market area code for the client's location. |

Example filter expression:

```

ip.src.metro_code eq "501"


```

For more information, refer to the [Fields reference](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/ip.src.metro%5Fcode/).

## 2025-10-30

  
**New TCP-based fields available in Rulesets**   

#### Build rules based on TCP transport and latency

Cloudflare now provides two new request fields in the Ruleset engine that let you make decisions based on whether a request used TCP and the measured TCP round-trip time between the client and Cloudflare. These fields help you understand protocol usage across your traffic and build policies that respond to network performance. For example, you can distinguish TCP from QUIC traffic or route high latency requests to alternative origins when needed.

---

#### New fields

| Field                             | Type    | Description                                                                                                                                                          |
| --------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| cf.edge.client\_tcp               | Boolean | Indicates whether the request used TCP. A value of true means the client connected using TCP instead of QUIC.                                                        |
| cf.timings.client\_tcp\_rtt\_msec | Number  | Reports the smoothed TCP round-trip time between the client and Cloudflare in milliseconds. For example, a value of 20 indicates roughly twenty milliseconds of RTT. |

Example filter expression:

```

cf.edge.client_tcp && cf.timings.client_tcp_rtt_msec < 100


```

More information can be found in the Rules language [fields reference](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/).

## 2025-06-09

  
**More flexible fallback handling — Custom Errors now support fetching assets returned with 4xx or 5xx status codes**   

[Custom Errors](https://developers.cloudflare.com/rules/custom-errors/) can now fetch and store [assets](https://developers.cloudflare.com/rules/custom-errors/create-rules/#create-a-custom-error-asset-dashboard) and [error pages](https://developers.cloudflare.com/rules/custom-errors/#error-pages) from your origin even if they are served with a 4xx or 5xx HTTP status code — previously, only 200 OK responses were allowed.

**What’s new:**

* You can now upload error pages and error assets that return error status codes (for example, 403, 500, 502, 503, 504) when fetched.
* These assets are stored and minified at the edge, so they can be reused across multiple Custom Error rules without triggering requests to the origin.

This is especially useful for retrieving error content or downtime banners from your backend when you can’t override the origin status code.

Learn more in the [Custom Errors](https://developers.cloudflare.com/rules/custom-errors/) documentation.

## 2025-06-09

  
**Match Workers subrequests by upstream zone — cf.worker.upstream\_zone now supported in Transform Rules**   

You can now use the [cf.worker.upstream\_zone](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/cf.worker.upstream%5Fzone/) field in [Transform Rules](https://developers.cloudflare.com/rules/transform/) to control rule execution based on whether a request originates from [Workers](https://developers.cloudflare.com/workers/), including subrequests issued by Workers in other zones.

![Match Workers subrequests by upstream zone in Transform Rules](https://developers.cloudflare.com/_astro/transform-rule-subrequest-matching.BeUBEN67_wWefn.webp) 

**What's new:**

* `cf.worker.upstream_zone` is now supported in Transform Rules expressions.
* Skip or apply logic conditionally when handling [Workers subrequests](https://developers.cloudflare.com/workers/platform/limits/#subrequests).

For example, to add a header when the subrequest comes from another zone:

Text in **Expression Editor** (replace `myappexample.com` with your domain):

```

(cf.worker.upstream_zone != "" and cf.worker.upstream_zone != "myappexample.com")


```

Selected operation under **Modify request header**: _Set static_

**Header name**: `X-External-Workers-Subrequest`

**Value**: `1`

This gives you more granular control in how you handle incoming requests for your zone.

Learn more in the [Transform Rules](https://developers.cloudflare.com/rules/transform/) documentation and [Rules language fields](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/) reference.

## 2025-05-30

  
**Fine-tune image optimization — WebP now supported in Configuration Rules**   

You can now enable [Polish](https://developers.cloudflare.com/images/polish/activate-polish/) with the `webp` format directly in [Configuration Rules](https://developers.cloudflare.com/rules/configuration-rules/), allowing you to optimize image delivery for specific routes, user agents, or A/B tests — without applying changes zone-wide.

**What’s new:**

* [WebP](https://developers.cloudflare.com/images/polish/compression/#webp) is now a supported [value](https://developers.cloudflare.com/rules/configuration-rules/settings/#polish) in the **Polish** setting for Configuration Rules.

This gives you more precise control over how images are compressed and delivered, whether you're targeting modern browsers, running experiments, or tailoring performance by geography or device type.

Learn more in the [Polish](https://developers.cloudflare.com/images/polish/) and [Configuration Rules](https://developers.cloudflare.com/rules/configuration-rules/) documentation.

## 2025-05-09

  
**More ways to match — Snippets now support Custom Lists, Bot Score, and WAF Attack Score**   

You can now use IP, Autonomous System (AS), and Hostname [custom lists](https://developers.cloudflare.com/waf/tools/lists/custom-lists/) to route traffic to [Snippets](https://developers.cloudflare.com/rules/snippets/) and [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/), giving you greater precision and control over how you match and process requests at the edge.

In Snippets, you can now also match on [Bot Score](https://developers.cloudflare.com/bots/concepts/bot-score/) and [WAF Attack Score](https://developers.cloudflare.com/waf/detections/attack-score/), unlocking smarter edge logic for everything from request filtering and mitigation to [tarpitting](https://developers.cloudflare.com/rules/snippets/examples/slow-suspicious-requests/) and logging.

**What’s new:**

* [Custom lists](https://developers.cloudflare.com/waf/tools/lists/custom-lists/) matching – Snippets and Cloud Connector now support user-created IP, AS, and Hostname lists via dashboard or [Lists API](https://developers.cloudflare.com/api/resources/rules/subresources/lists/methods/list/). Great for shared logic across zones.
* [Bot Score](https://developers.cloudflare.com/bots/concepts/bot-score/) and [WAF Attack Score](https://developers.cloudflare.com/waf/detections/attack-score/) – Use Cloudflare’s intelligent traffic signals to detect bots or attacks and take advanced, tailored actions with just a few lines of code.
![New fields in Snippets](https://developers.cloudflare.com/_astro/snippets-lists-scores.D05l6zgc_ZG4Rof.webp) 

These enhancements unlock new possibilities for building smarter traffic workflows with minimal code and maximum efficiency.

Learn more in the [Snippets](https://developers.cloudflare.com/rules/snippets/) and [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/) documentation.

## 2025-04-24

  
**Custom Errors are now Generally Available**   

[Custom Errors](https://developers.cloudflare.com/rules/custom-errors/) are now generally available for all paid plans — bringing a unified and powerful experience for customizing error responses at both the zone and account levels.

You can now manage **Custom Error Rules**, **Custom Error Assets**, and redesigned **Error Pages** directly from the Cloudflare dashboard. These features let you deliver tailored messaging when errors occur, helping you maintain brand consistency and improve user experience — whether it’s a 404 from your origin or a security challenge from Cloudflare.

What's new:

* **Custom Errors are now GA** – Available on all paid plans and ready for production traffic.
* **UI for Custom Error Rules and Assets** – Manage your zone-level rules from the Rules > Overview and your zone-level assets from the Rules > Settings tabs.
* **Define inline content or upload assets** – Create custom responses directly in the rule builder, upload new or reuse previously stored assets.
* **Refreshed UI and new name for Error Pages** – Formerly known as “Custom Pages,” Error Pages now offer a cleaner, more intuitive experience for both zone and account-level configurations.
* **Powered by Ruleset Engine** – Custom Error Rules support [conditional logic](https://developers.cloudflare.com/ruleset-engine/rules-language/) and override Error Pages for 500 and 1000 class errors, as well as errors originating from your origin or [other Cloudflare products](https://developers.cloudflare.com/ruleset-engine/reference/phases-list/). You can also configure [Response Header Transform Rules](https://developers.cloudflare.com/rules/transform/response-header-modification/) to add, change, or remove HTTP headers from responses returned by Custom Error Rules.

Learn more in the [Custom Errors documentation](https://developers.cloudflare.com/rules/custom-errors/).

## 2025-04-09

  
**Cloudflare Snippets are now Generally Available**   
![Cloudflare Snippets are now GA](https://developers.cloudflare.com/_astro/snippets-ga.BJr3csvv_Z2q49jT.webp) 

[Cloudflare Snippets](https://developers.cloudflare.com/rules/snippets/) are now generally available at no extra cost across all paid plans — giving you a fast, flexible way to programmatically control HTTP traffic using lightweight JavaScript.

You can now use Snippets to modify HTTP requests and responses with confidence, reliability, and scale. Snippets are production-ready and deeply integrated with Cloudflare Rules, making them ideal for everything from quick dynamic header rewrites to advanced routing logic.

What's new:

* **Snippets are now GA** – Available at no extra cost on all Pro, Business, and Enterprise plans.
* **Ready for production** – Snippets deliver a production-grade experience built for scale.
* **Part of the Cloudflare Rules platform** – Snippets inherit request modifications from other Cloudflare products and support sequential execution, allowing you to run multiple Snippets on the same request and apply custom modifications step by step.
* **Trace integration** – Use [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) to see which Snippets were triggered on a request — helping you understand traffic flow and debug more effectively.  
![Snippets shown in Cloudflare Trace results](https://developers.cloudflare.com/_astro/snippets-ga-trace.WlCshaFo_1WNo07.webp)

Learn more in the [launch blog post ↗](https://blog.cloudflare.com/snippets/).

## 2025-02-12

  
**Increased Cloudflare Rules limits**   

We have upgraded and streamlined [Cloudflare Rules](https://developers.cloudflare.com/rules/) limits across all plans, simplifying rule management and improving scalability for everyone.

**New limits by product:**

* [Bulk Redirects](https://developers.cloudflare.com/rules/url-forwarding/bulk-redirects/)  
   * Free: **20** → **10,000** URL redirects across lists  
   * Pro: **500** → **25,000** URL redirects across lists  
   * Business: **500** → **50,000** URL redirects across lists  
   * Enterprise: **10,000** → **1,000,000** URL redirects across lists
* [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/)  
   * Free: **5** → **10** connectors  
   * Enterprise: **125** → **300** connectors
* [Custom Errors](https://developers.cloudflare.com/rules/custom-errors/)  
   * Pro: **5** → **25** error assets and rules  
   * Business: **20** → **50** error assets and rules  
   * Enterprise: **50** → **300** error assets and rules
* [Snippets](https://developers.cloudflare.com/rules/snippets/)  
   * Pro: **10** → **25** code snippets and rules  
   * Business: **25** → **50** code snippets and rules  
   * Enterprise: **50** → **300** code snippets and rules
* [Cache Rules](https://developers.cloudflare.com/cache/how-to/cache-rules/), [Configuration Rules](https://developers.cloudflare.com/rules/configuration-rules/), [Compression Rules](https://developers.cloudflare.com/rules/compression-rules/), [Origin Rules](https://developers.cloudflare.com/rules/origin-rules/), [Single Redirects](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/), and [Transform Rules](https://developers.cloudflare.com/rules/transform/)  
   * Enterprise: **125** → **300** rules

Gradual rollout

Limits are updated gradually. Some customers may still see previous limits until the rollout is fully completed in the first half of 2025.

## 2025-02-11

  
**Custom Errors (beta): Stored Assets & Account-level Rules**   

We're introducing [Custom Errors](https://developers.cloudflare.com/rules/custom-errors/) (beta), which builds on our existing Custom Error Responses feature with new asset storage capabilities.

This update allows you to store externally hosted error pages on Cloudflare and reference them in custom error rules, eliminating the need to supply inline content.

This brings the following new capabilities:

* **Custom error assets** – Fetch and store external error pages at the edge for use in error responses.
* **Account-Level custom errors** – Define error handling rules and assets at the account level for consistency across multiple zones. Zone-level rules take precedence over account-level ones, and assets are not shared between levels.

You can use Cloudflare API to upload your existing assets for use with Custom Errors:

Terminal window

```

curl "https://api.cloudflare.com/client/v4/zones/{zone_id}/custom_pages/assets" \

--header "Authorization: Bearer <API_TOKEN>" \

--header 'Content-Type: application/json' \

--data '{

  "name": "maintenance",

  "description": "Maintenance template page",

  "url": "https://example.com/"

}'


```

You can then reference the stored asset in a Custom Error rule:

Terminal window

```

curl --request PUT \

"https://api.cloudflare.com/client/v4/zones/{zone_id}/rulesets/phases/http_custom_errors/entrypoint" \

--header "Authorization: Bearer <API_TOKEN>" \

--header 'Content-Type: application/json' \

--data '{

  "rules": [

    {

      "action": "serve_error",

      "action_parameters": {

        "asset_name": "maintenance",

        "content_type": "text/html",

        "status_code": 503

      },

      "enabled": true,

      "expression": "http.request.uri.path contains \"error\""

    }

  ]

}'


```

## 2025-01-29

  
**New Snippets Code Editor**   

The new [Snippets](https://developers.cloudflare.com/rules/snippets/) code editor lets you edit Snippet code and rule in one place, making it easier to test and deploy changes without switching between pages.

![New Snippets code editor](https://developers.cloudflare.com/_astro/snippets-new-editor.CaoIu2_-_Z2rsmyM.webp) 

What’s new:

* **Single-page editing for code and rule** – No need to jump between screens.
* **Auto-complete & syntax highlighting** – Get suggestions and avoid mistakes.
* **Code formatting & refactoring** – Write cleaner, more readable code.

Try it now in [Rules > Snippets ↗](https://dash.cloudflare.com/?to=/:account/:zone/rules/snippets).

## 2025-01-09

  
**New Rules Overview Interface**   

**Rules Overview** gives you a single page to manage all your [Cloudflare Rules](https://developers.cloudflare.com/rules/).

What you can do:

* **See all your rules in one place** – No more clicking around.
* **Find rules faster** – Search by name.
* **Understand execution order** – See how rules run in sequence.
* **Debug easily** – Use [Trace](https://developers.cloudflare.com/rules/trace-request/) without switching tabs.

Check it out in [Rules > Overview ↗](https://dash.cloudflare.com/?to=/:account/:zone/rules/overview).

## 2024-12-11

  
**Terraform Support for Snippets**   

Now, you can manage [Cloudflare Snippets](https://developers.cloudflare.com/rules/snippets/) with [Terraform](https://developers.cloudflare.com/terraform/). Use infrastructure-as-code to deploy and update Snippet code and rules without manual changes in the dashboard.

Example Terraform configuration:

```

resource "cloudflare_snippet" "my_snippet" {

  zone_id  = "<ZONE_ID>"

  name = "my_test_snippet_1"

  main_module = "file1.js"

  files {

    name = "file1.js"

    content = file("file1.js")

  }

}


resource "cloudflare_snippet_rules" "cookie_snippet_rule" {

  zone_id  = "<ZONE_ID>"

  rules {

    enabled = true

    expression = "http.cookie eq \"a=b\""

    description = "Trigger snippet on specific cookie"

    snippet_name = "my_test_snippet_1"

  }

  depends_on = [cloudflare_snippet.my_snippet]

}


```

Learn more in the [Configure Snippets using Terraform](https://developers.cloudflare.com/rules/snippets/create-terraform/) documentation.

## 2024-11-22

  
**Cloud Connector Now Supports R2**   

Now, you can use [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/) to route traffic to your [R2 buckets](https://developers.cloudflare.com/r2/) based on URLs, headers, geolocation, and more.

Example setup:

Terminal window

```

curl --request PUT \

"https://api.cloudflare.com/client/v4/zones/{zone_id}/cloud_connector/rules" \

--header "Authorization: Bearer <API_TOKEN>" \

--header "Content-Type: application/json" \

--data '[

  {

    "expression": "http.request.uri.path wildcard \"/images/*\"",

    "provider": "cloudflare_r2",

    "description": "Connect to R2 bucket containing images",

    "parameters": {

      "host": "mybucketcustomdomain.example.com"

    }

  }

]'


```

Get started using [Cloud Connector](https://developers.cloudflare.com/rules/cloud-connector/) documentation.

## 2024-10-23

  
**Simplified UI for URL Rewrites**   

It’s now easy to create **wildcard-based [URL Rewrites](https://developers.cloudflare.com/rules/transform/url-rewrite/)**. No need for complex functions—just define your patterns and go.

![Rules Overview Interface](https://developers.cloudflare.com/_astro/create-url-rewrite-rule.DIgpB8IB_ZNTjfK.webp) 

What’s improved:

* **Full wildcard support** – Create rewrite patterns using intuitive interface.
* **Simplified rule creation** – No need for complex functions.

Try it via [creating a Rewrite URL rule in the dashboard](https://developers.cloudflare.com/rules/transform/url-rewrite/create-dashboard/#wildcard-pattern-parameters).

## 2024-09-20

**Automatic DNS Validation for Cloudflare Rules**

The Cloudflare dashboard now automatically validates [DNS records ↗](https://developers.cloudflare.com/dns/proxy-status/) and [Cloudflare for SaaS custom hostnames ↗](https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/domain-support/) for rules targeting specific hostnames or URLs. To prevent misconfigured rules and ensure smoother deployments, you will get proactive warnings for missing or misconfigured DNS records and custom hostnames.

## 2024-09-17

**Compression Rules available to all plans with Zstandard support**

[Compression Rules ↗](https://developers.cloudflare.com/rules/compression-rules/) now support Zstandard compression and are available in all Cloudflare plans. Users in the Free plan will gradually get access throughout 2024.

## 2024-09-13

**Snippets now available in beta**

[Cloudflare Snippets ↗](https://developers.cloudflare.com/rules/snippets/) have transitioned from alpha to beta.

## 2024-09-10

**wildcard\_replace() function now supported in URL rewrites**

You can now use the [wildcard\_replace() ↗](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#wildcard%5Freplace) function in rewrite expressions of [URL rewrites ↗](https://developers.cloudflare.com/rules/transform/url-rewrite/).

## 2024-09-05

**New Rules Templates for one-click rule creation**

The new **Rules** \> **Templates** page in the Cloudflare dashboard allows you to create common rules with a single click, featuring dozens of pre-built templates. You can also access these templates directly from each product's rule builder. Also, explore the [Examples gallery ↗](https://developers.cloudflare.com/rules/examples/) in the developer docs for real-world use cases and inspiration.

## 2024-08-22

**Simplified UI for Single Redirects with wildcard support**

The simplified UI for [Single Redirects ↗](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/) is now available to all users, making URL redirects easier and more intuitive. This update builds on the recent [wildcard support ↗](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#wildcard%5Freplace) in Ruleset Engine products. Access the new UI under **Rules > Redirect Rules**. Learn more about wildcard support and our open-source Rust crate in the [blog post ↗](https://blog.cloudflare.com/wildcard-rules).

## 2024-08-20

**Cloud Connector now available to all customers**

Cloud Connector (beta) is now available to all customers. For setup details, refer to the [documentation ↗](https://developers.cloudflare.com/rules/cloud-connector/), explore [examples ↗](https://developers.cloudflare.com/rules/cloud-connector/examples/), and check out the [blog post ↗](https://blog.cloudflare.com/cloud-connector).

## 2024-08-16

**Cloud Connector now available to all free customers**

Cloud Connector (beta) is now available to all free and a subset of paid customers. This rollout will be [gradually extended ↗](https://developers.cloudflare.com/rules/cloud-connector/#availability) to all Cloudflare users, simplifying multi-cloud management and enhancing integration with Cloudflare's Connectivity Cloud. For more information, refer to the [blog post ↗](https://blog.cloudflare.com/cloud-connector).

## 2024-08-12

**Cloudflare Snippets limits have been upgraded**

Cloudflare Snippets (alpha) now allow multiple subrequests depending on your plan. For more information, refer to the [Availability ↗](https://developers.cloudflare.com/rules/snippets/#availability).

## 2024-07-31

**Wildcard support added to Ruleset Engine products**

Wildcards are now supported across our Ruleset Engine-based products, including Single Redirects, Cache Rules, Transform Rules, WAF, Waiting Room, and more:

* You can now use the `wildcard` and `strict wildcard` operators with any string field in the Ruleset Engine, such as full URI, host, headers, cookies, user-agent, and country. For more details, refer to [Operators ↗](https://developers.cloudflare.com/ruleset-engine/rules-language/operators/) and [Wildcard matching ↗](https://developers.cloudflare.com/ruleset-engine/rules-language/operators/#wildcard-matching).
* In [Single Redirects ↗](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/), the `wildcard_replace()` function allows you to use segments matched by the `wildcard` and `strict wildcard` operators in redirect URL targets. For more information, refer to [Functions ↗](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#wildcard%5Freplace).

## 2024-07-01

**Cloudflare Snippets now available to all paid customers**

Cloudflare Snippets (alpha) are now available to all paid customers.

## 2024-06-03

**Cloudflare Snippets now available to all Enterprise customers**

Cloudflare Snippets (alpha) are now available to all Enterprise customers. Customers in other paid plans will gradually get access throughout 2024.

## 2024-05-14

**Page Rules migration**

The [Page Rules migration guide ↗](https://developers.cloudflare.com/rules/reference/page-rules-migration/) is now available for users interested in transitioning to modern Rules features instead of Page Rules. Explore the guide for detailed instructions on migrating your configurations.

## 2024-05-13

**New Configuration Rules setting for Web Analytics (RUM)**

You can now turn off Cloudflare Web Analytics, also known as Real User Monitoring (RUM), for specific requests using a configuration rule.

## 2024-04-29

**New Configuration Rules setting for Cloudflare Fonts**

You can now turn on or off Cloudflare Fonts for specific requests using a configuration rule.

## 2024-03-22

**New TLS fields in rule expressions**

Customers can now use new fields `cf.tls_client_hello_length` (the length of the client hello message sent in a TLS handshake), `cf.tls_client_random` (the value of the 32-byte random value provided by the client in a TLS handshake), and `cf.tls_client_extensions_sha1` (the SHA-1 fingerprint of TLS client extensions) in various products built on Ruleset Engine.

## 2024-03-20

**Origin Rules now allow port numbers in Host Header Override**

Customers can now use arbitrary port numbers in Host Header Override in Origin Rules. Previously, only hostname was allowed as a value (for example, `example.com`). Now, you can set the value to `hostname:port` (for example, `example.com:1234`) as well.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/changelog/","name":"Rules changelog"}}]}
```

---

---
title: Rules language
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/reference/link-rule-language.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Rules language

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/reference/","name":"Reference"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/reference/link-rule-language/","name":"Rules language"}}]}
```

---

---
title: Page Rules migration guide
description: Cloudflare is continuously improving its platform to deliver more powerful and scalable tools for managing your configurations. To help you take full advantage of these improvements, we recommend using modern Rules features for new implementations. These products address the limitations of Page Rules while providing greater flexibility, scalability, and ease of use.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/reference/page-rules-migration.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Page Rules migration guide

Cloudflare is continuously improving its platform to deliver more powerful and scalable tools for managing your configurations. To help you take full advantage of these improvements, we recommend using [modern Rules features](https://developers.cloudflare.com/rules/) for new implementations. These products address the limitations of Page Rules while providing greater flexibility, scalability, and ease of use.

For a quick start, explore the one-click templates available in the Cloudflare dashboard in **Rules** \> **Overview**. These templates simplify common configurations like redirects, rewrites and header modifications, making setup faster and easier.

## Page Rules migration

To make the transition seamless, Cloudflare will handle the migration of your existing Page Rules automatically. This process is planned for late 2025 or beyond, with no action required on your part. You will receive advance notification before any changes are made.

If you wish to explore the benefits of modern Rules features sooner, you can begin adopting them today. Doing so allows you to:

* Take advantage of modern features and capabilities sooner.
* Customize and refine your rules to match your evolving needs.

To assist with this process, we provide you with a comprehensive mapping between Page Rules settings and modern Rules products in this guide.

## Why transition?

Cloudflare Page Rules has several fundamental limitations, such as triggering solely based on URL patterns and being limited to 125 rules per zone for performance reasons. These rules are also complex to debug when multiple page rules apply to the same incoming request.

In 2022, we announced in our blog post [The future of Page Rules ↗](https://blog.cloudflare.com/future-of-page-rules) that Page Rules would be replaced with a suite of dedicated products, each built to be best-of-breed and put more power into the hands of our users. The new Rules products — [Configuration Rules](https://developers.cloudflare.com/rules/configuration-rules/), [Compression Rules](https://developers.cloudflare.com/rules/compression-rules/), [Origin Rules](https://developers.cloudflare.com/rules/origin-rules/), [Redirects](https://developers.cloudflare.com/rules/url-forwarding/), and [Transform Rules](https://developers.cloudflare.com/rules/transform/) — are now generally available (GA) and have already been adopted by tens of thousands of Cloudflare customers.

Improvements in modern Rules features include:

* **New engine**: New Rules features are powered by the [Ruleset Engine](https://developers.cloudflare.com/ruleset-engine/), which offers versatile configuration with a robust language that supports many HTTP request and response fields.
* **Improved scalability**: Thanks to the improved scalability, Cloudflare plans now have increased quotas.
* **Easier troubleshooting**: Rule execution is more predictable, since each rule operates independently, simplifying troubleshooting. Additionally, [Cloudflare Trace](https://developers.cloudflare.com/rules/trace-request/) helps understand rule interactions.
* **Improved consistency**: New Rules features also ensure consistency, with common fields and capabilities shared across products, offering a seamless experience and predictable Terraform configurations.

## Key differences

The evaluation and execution order of Rules features is different from Page Rules:

* **Rule matching logic**: Page Rules apply the first matching rule (first match wins). In contrast, modern Rules are stackable, meaning multiple matching rules can combine and apply to the same request (last match wins). For example, if multiple cache rules match the same URL, the features in those rules will all apply in order.
* **Action separation**: A Page Rule may include multiple actions for different products that are applied in a sequence selected by the customer within the Page Rule itself. Modern Rules features are evaluated [in a fixed sequence](https://developers.cloudflare.com/rules/origin-rules/#execution-order), with customers defining the rule order within a product [phase](https://developers.cloudflare.com/ruleset-engine/reference/phases-list/).
* **Precedence**: Modern Rules features take precedence over Page Rules. For instance, if both define caching settings for the same path, Cache Rules will override Page Rules.
* **Caching behavior**: In Cache Rules, selecting **Eligible for cache** automatically enables **Cache Everything** by default. To maintain the exact behavior of Page Rules, you may need to [adjust your configuration](https://developers.cloudflare.com/cache/how-to/cache-rules/page-rules-migration/).
* **Interactions with Workers**: Requests handled by Workers will suppress Page Rules actions, but they will not suppress actions from modern Rules features.

## Convert Page Rules URLs to filter expressions

Modern Rules use filter expressions instead of URL patterns. These expressions, built with the Rules language, allow greater precision by leveraging [fields](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/), [functions](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/), and [operators](https://developers.cloudflare.com/ruleset-engine/rules-language/operators/).

The following example demonstrates the use of the [http.request.full\_uri](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/http.request.full%5Furi/) field and the `wildcard` operator for [wildcard matching](https://developers.cloudflare.com/ruleset-engine/rules-language/operators/#wildcard-matching):

A **Page Rules URL** like:

`example.com/*/downloads/*.txt`

becomes a **filter expression** such as:

`http.request.full_uri wildcard "http*://example.com/*/downloads/*.txt*"`

[Single Redirects](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/create-dashboard/) and [URL Rewrite Rules](https://developers.cloudflare.com/rules/transform/url-rewrite/create-dashboard/) also offer a simplified view called **Wildcard pattern**, allowing you to specify URL patterns (`http*://example.com/*/downloads/*.txt*`) without specifying the full filter expression (`http.request.full_uri wildcard "http*://example.com/*/downloads/*.txt*"`).

### Important considerations

* **Protocol scheme**: Page Rules URL matching does not include the URI scheme (for example, `http://` or `https://`) unless explicitly included in the rule. Filter expressions using `http.request.full_uri` field, however, require matching the full URI, including the protocol scheme. To make your filter expression scheme-agnostic, use `http*://` as a wildcard for both `http://` and `https://`.
* **Query strings**: Page Rules ignore query strings unless they are part of the rule URL. Filter expressions include the query string automatically, as part of the `http.request.full_uri` field. To ensure query strings do not affect your matching, append a `*` wildcard at the end of your filter expression, such as `.txt*`.

## Feature correspondence table

To help you map existing Page Rules to modern Rules products, this table outlines how Page Rules settings translate to modern Rules and provides examples for common configurations.

Also, to streamline common configurations, the Cloudflare dashboard now includes dozens of one-click templates, available in **Rules** \> **Overview**. These templates enable you to deploy commonly used features — such as redirects, rewrites, and header modifications — instantly, with pre-filled filter expressions and actions. Explore these templates in the dashboard for a faster setup.

| Page Rules setting          | New implementation uses...           | Migration/Replacement instructions                                          |
| --------------------------- | ------------------------------------ | --------------------------------------------------------------------------- |
| Always Use HTTPS            | Redirect Rules (Single Redirects)    | [Migrate Always Use HTTPS](#migrate-always-use-https)                       |
| Browser Cache TTL           | Cache Rules                          | [Migrate Browser Cache TTL](#migrate-browser-cache-ttl)                     |
| Browser Integrity Check     | Configuration Rules                  | [Migrate Browser Integrity Check](#migrate-browser-integrity-check)         |
| Bypass Cache on Cookie      | Cache Rules                          | [Migrate Bypass Cache on Cookie](#migrate-bypass-cache-on-cookie)           |
| Cache By Device Type        | Cache Rules                          | [Migrate Cache By Device Type](#migrate-cache-by-device-type)               |
| Cache Deception Armor       | Cache Rules                          | [Migrate Cache Deception Armor](#migrate-cache-deception-armor)             |
| Cache Level                 | Cache Rules                          | [Migrate Cache Level](#migrate-cache-level-cache-everything)                |
| Cache on Cookie             | Cache Rules                          | [Migrate Cache on Cookie](#migrate-cache-on-cookie)                         |
| Cache TTL by status code    | Cache Rules                          | [Migrate Cache TTL by status code](#migrate-cache-ttl-by-status-code)       |
| Custom Cache Key            | Cache Rules                          | [Migrate Custom Cache Key](#migrate-custom-cache-key)                       |
| Disable Apps                | Configuration Rules                  | [Migrate Disable Apps](#migrate-disable-apps)                               |
| Disable Performance         | N/A (deprecated)                     | [Replace Disable Performance](#replace-disable-performance)                 |
| Disable Railgun             | N/A (deprecated)                     | N/A                                                                         |
| Disable Security            | N/A (deprecated)                     | [Replace Disable Security](#replace-disable-security)                       |
| Disable Zaraz               | Configuration Rules                  | [Migrate Disable Zaraz](#migrate-disable-zaraz)                             |
| Edge Cache TTL              | Cache Rules                          | [Migrate Edge Cache TTL](#migrate-edge-cache-ttl)                           |
| Email Obfuscation           | Configuration Rules                  | [Migrate Email Obfuscation](#migrate-email-obfuscation)                     |
| Forwarding URL              | Redirect Rules (Single Redirects)    | [Migrate Forwarding URL](#migrate-forwarding-url)                           |
| Host Header Override        | Origin Rules                         | [Migrate Host Header Override](#migrate-host-header-override)               |
| IP Geolocation Header       | Transform Rules (Managed Transforms) | [Migrate IP Geolocation Header](#migrate-ip-geolocation-header)             |
| Opportunistic Encryption    | Configuration Rules                  | [Migrate Opportunistic Encryption](#migrate-opportunistic-encryption)       |
| Origin Cache Control        | Cache Rules                          | [Migrate Origin Cache Control](#migrate-origin-cache-control)               |
| Origin Error Page Pass-thru | Cache Rules                          | [Migrate Origin Error Page Pass-thru](#migrate-origin-error-page-pass-thru) |
| Polish                      | Configuration Rules                  | [Migrate Polish](#migrate-polish)                                           |
| Query String Sort           | Cache Rules                          | [Migrate Query String Sort](#migrate-query-string-sort)                     |
| Resolve Override            | Origin Rules                         | [Migrate Resolve Override](#migrate-resolve-override)                       |
| Respect Strong ETags        | Cache Rules                          | [Migrate Respect Strong ETags](#migrate-respect-strong-etags)               |
| Response Buffering          | N/A (deprecated)                     | N/A                                                                         |
| Rocket Loader               | Configuration Rules                  | [Migrate Rocket Loader](#migrate-rocket-loader)                             |
| Security Level              | Configuration Rules                  | [Migrate Security Level](#migrate-security-level)                           |
| True Client IP Header       | Transform Rules (Managed Transforms) | [Migrate True Client IP Header](#migrate-true-client-ip-header)             |
| SSL                         | Configuration Rules                  | [Migrate SSL](#migrate-ssl)                                                 |
| Web Application Firewall    | N/A (deprecated)                     | N/A                                                                         |

### Migrate Always Use HTTPS

* [ Dashboard ](#tab-panel-6016)
* [ Visual guide ](#tab-panel-6017)

**Context:**

You configured a Page Rule to perform an automatic redirect from HTTP to HTTPS for all subdomains of `example.com` and the `example.com` domain itself:

* **URL** `*example.com/*`
* **Setting**: _Always Use HTTPS_

**How to migrate**:

1. [Create a single redirect](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/create-dashboard/) to always redirect HTTP requests to HTTPS. You can select the **Redirect from HTTP to HTTPS** rule template or enter the following rule configuration:  
   * **If incoming requests match**: Wildcard pattern  
         * **Request URL**: `http://*`  
   * **Then**:  
         * **Target URL**: `https://${1}`  
         * **Status code**: _301_  
         * **Preserve query string**: Enabled
2. Turn off your existing Page Rule and validate the behavior of the redirect you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                | Migrate to a single redirect                                                                                                                                              |
| --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Always Use HTTPS' setting](https://developers.cloudflare.com/_astro/pr-always-use-https.CUl_pNfb_ZwfSLG.webp) | ![Single redirect matching the 'Always Use HTTPS' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-always-use-https-new.BOryxIv0_jNt3t.webp) |

### Migrate Automatic HTTPS Rewrites

* [ Dashboard ](#tab-panel-6018)
* [ Visual guide ](#tab-panel-6019)

**Context:**

You configured a Page Rule turning on Automatic HTTPS Rewrites for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Automatic HTTPS Rewrites_
* **Value**: On

**How to migrate**:

1. [Create a configuration rule](https://developers.cloudflare.com/rules/configuration-rules/create-dashboard/) to always rewrite HTTP links to HTTPS for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then the settings are**:  
         * **Setting**: Automatic HTTPS Rewrites  
         * **Value**: On
2. Turn off your existing Page Rule and validate the behavior of the configuration rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                                 | Migrate to a configuration rule                                                                                                                                                               |
| -------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Automatic HTTPS Rewrites' setting](https://developers.cloudflare.com/_astro/pr-automatic-https-rewrites.CLJyVtYV_Z26qFhi.webp) | ![Configuration rule matching the 'Automatic HTTPS Rewrites' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-automatic-https-rewrites-new.Bkd1FpXw_ZpdWVq.webp) |

### Migrate Browser Cache TTL

* [ Dashboard ](#tab-panel-6048)
* [ Visual guide ](#tab-panel-6049)

**Context:**

You configured a Page Rule adjusting browser cache TTL to one day for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Browser Cache TTL_
* **Enter Browser Cache TTL**: _a day_

**How to migrate**:

1. [Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to adjust browser cache TTL for caching resources in the browser to one day for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then**:  
         * **Cache eligibility**: Eligible for cache  
         * **Browser TTL**: Override origin and use this TTL  
         * **Input time-to-live (TTL)**: _1 day_  
Warning  
The default behavior of Cache Rules is different from Page Rules. Refer to [Key differences](#key-differences) for more information.
2. Turn off your existing Page Rule and validate the behavior of the cache rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                   | Migrate to a cache rule                                                                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Browser Cache TTL' setting](https://developers.cloudflare.com/_astro/pr-browser-cache-ttl.BsUhcEXO_Z15nk2E.webp) | ![Cache rule matching the 'Browser Cache TTL' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-browser-cache-ttl-new.CFYgSIfM_28xvmr.webp) |

### Migrate Browser Integrity Check

* [ Dashboard ](#tab-panel-6020)
* [ Visual guide ](#tab-panel-6021)

**Context:**

You configured a Page Rule turning on Browser Integrity Check for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Browser Integrity Check_
* **Value**: On

**How to migrate**:

1. [Create a configuration rule](https://developers.cloudflare.com/rules/configuration-rules/create-dashboard/) to turn on Browser Integrity Check for protecting against bots and threats for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then the settings are**:  
         * **Setting**: Browser Integrity Check  
         * **Value**: On
2. Turn off your existing Page Rule and validate the behavior of the configuration rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                               | Migrate to a configuration rule                                                                                                                                                             |
| ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Browser Integrity Check' setting](https://developers.cloudflare.com/_astro/pr-browser-integrity-check.0TsdxTXD_Z1Wutmk.webp) | ![Configuration rule matching the 'Browser Integrity Check' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-browser-integrity-check-new.DABehTnG_ZCT1QP.webp) |

### Migrate Bypass Cache on Cookie

* [ Dashboard ](#tab-panel-6050)
* [ Visual guide ](#tab-panel-6051)

**Context:**

You configured a Page Rule turning on Bypass Cache on Cookie for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Bypass Cache on Cookie_
* **Enter value**: `test_cookie`

**How to migrate**:

1. [Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to bypass cache for requests containing cookie `test_cookie` for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com" AND Cookie contains "test-cookie"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com" and http.cookie contains "test-cookie")`  
   * **Then**:  
         * **Cache eligibility**: Bypass cache  
Warning  
The default behavior of Cache Rules is different from Page Rules. Refer to [Key differences](#key-differences) for more information.
2. Turn off your existing Page Rule and validate the behavior of the cache rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                            | Migrate to a cache rule                                                                                                                                                            |
| --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Bypass Cache on Cookie' setting](https://developers.cloudflare.com/_astro/pr-bypass-cache-on-cookie.h4Mq0pkO_ZS1hzt.webp) | ![Cache rule matching the 'Bypass Cache on Cookie' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-bypass-cache-on-cookie-new.BeJb7-Bu_Z1vl7rE.webp) |

### Migrate Cache By Device Type

* [ Dashboard ](#tab-panel-6052)
* [ Visual guide ](#tab-panel-6053)

**Context:**

You configured a Page Rule turning on Cache By Device Type for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Cache By Device Type_
* **Value**: On

**How to migrate**:

1. [Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to cache content based on user agent or device type for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then**:  
         * **Cache eligibility**: Eligible for cache  
         * **Setting**: Cache key  
                  * **Cache by device type**: On  
Warning  
The default behavior of Cache Rules is different from Page Rules. Refer to [Key differences](#key-differences) for more information.
2. Turn off your existing Page Rule and validate the behavior of the cache rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                        | Migrate to a cache rule                                                                                                                                                      |
| ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Cache By Device Type' setting](https://developers.cloudflare.com/_astro/pr-cache-by-device-type.D_TlBAdc_1ORjXt.webp) | ![Cache rule matching the 'Cache By Device Type' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-cache-by-device-type-new.j6a5kEn__kmLw1.webp) |

### Migrate Cache Deception Armor

* [ Dashboard ](#tab-panel-6054)
* [ Visual guide ](#tab-panel-6055)

**Context:**

You configured a Page Rule turning on Cache Deception Armor for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: Cache Deception Armor

**How to migrate**:

1. [Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to protect against cache deception attacks for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then**:  
         * **Cache eligibility**: Eligible for cache  
         * **Setting**: Cache key  
                  * **Cache deception armor**: On  
Warning  
The default behavior of Cache Rules is different from Page Rules. Refer to [Key differences](#key-differences) for more information.
2. Turn off your existing Page Rule and validate the behavior of the cache rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                          | Migrate to a cache rule                                                                                                                                                          |
| ------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Cache Deception Armor' setting](https://developers.cloudflare.com/_astro/pr-cache-deception-armor.CAh-wrs4_ZaMxP1.webp) | ![Cache rule matching the 'Cache Deception Armor' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-cache-deception-armor-new.BT9l5EUw_Z1UI9gA.webp) |

### Migrate Cache Level (Cache Everything)

* [ Dashboard ](#tab-panel-6056)
* [ Visual guide ](#tab-panel-6057)

**Context:**

You configured a Page Rule turning on caching of all assets for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Cache Level_
* **Select Cache Level**: _Cache Everything_

**How to migrate**:

1. [Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to adjust cache level for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then**:  
         * **Cache eligibility**: Eligible for cache  
Warning  
The default behavior of Cache Rules is different from Page Rules. Refer to [Key differences](#key-differences) for more information.
2. Turn off your existing Page Rule and validate the behavior of the cache rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                                    | Migrate to a cache rule                                                                                                                                                                   |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Cache Level' set to 'Cache Everything'](https://developers.cloudflare.com/_astro/pr-cache-level-everything.DdVHSP6R_Z1SVoGM.webp) | ![Cache rule matching the 'Cache Level: Cache Everything' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-cache-level-everything-new.CWHQUlgp_Z1GCIwi.webp) |

### Migrate Cache on Cookie

* [ Dashboard ](#tab-panel-6058)
* [ Visual guide ](#tab-panel-6059)

**Context:**

You configured a Page Rule turning on caching for responses that contained cookie `test-cookie` for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Cache on Cookie_
* **Enter value**: `test-cookie`

**How to migrate**:

1. [Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to cache responses containing cookie `test_cookie` for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com" AND Cookie contains "test-cookie"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com" and http.cookie contains "test-cookie")`  
   * **Then**:  
         * **Cache eligibility**: Eligible for cache  
Warning  
The default behavior of Cache Rules is different from Page Rules. Refer to [Key differences](#key-differences) for more information.
2. Turn off your existing Page Rule and validate the behavior of the cache rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                             | Migrate to a cache rule                                                                                                                                             |
| ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Cache on Cookie' setting](https://developers.cloudflare.com/_astro/pr-cache-on-cookie.ByvIqgIj_NLhPm.webp) | ![Cache rule matching the 'Cache on Cookie' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-cache-on-cookie-new.PWLmyHmb_Z61apS.webp) |

### Migrate Cache TTL by status code

* [ Dashboard ](#tab-panel-6060)
* [ Visual guide ](#tab-panel-6061)

**Context:**

You configured a Page Rule turning on caching of every response with status code between `200` and `599` for one day, for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Cache TTL by status code_
* **Status code or enter range**: `200-599`
* **Select option**: _a day_

**How to migrate**:

1. [Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to cache responses with status code between `200` and `599` for one day for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
         * **Then**:  
                  * **Cache eligibility**: Eligible for cache  
                  * **Setting**: Edge TTL  
                              * Use cache-control header if present, use default Cloudflare caching behavior if not  
                              * **Status code TTL**:  
                                             * **Scope**: _Range_  
                                             * **From**: _200_  
                                             * **To**: _599_  
                                             * **Duration**: _1 day_  
Warning  
The default behavior of Cache Rules is different from Page Rules. Refer to [Key differences](#key-differences) for more information.
2. Turn off your existing Page Rule and validate the behavior of the cache rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                                   | Migrate to a cache rule                                                                                                                                                               |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with the 'Cache TTL by status code' setting](https://developers.cloudflare.com/_astro/pr-cache-ttl-by-status-code.BEFPIQlk_gCwHH.webp) | ![Cache rule matching the 'Cache TTL by status code' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-cache-ttl-by-status-code-new.D7fRKD4K_Zkzrqq.webp) |

### Migrate Custom Cache Key

* [ Dashboard ](#tab-panel-6062)
* [ Visual guide ](#tab-panel-6063)

**Context:**

You configured a Page Rule setting a custom cache key for all query string parameters, for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Custom Cache Key_  
   * **Query String**: All query string parameters

**How to migrate**:

1. [Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to set a custom cache key for all query string parameters, for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then**:  
         * **Cache eligibility**: Eligible for cache  
         * **Setting**: Cache key  
                  * **Query string**: All query string parameters  
Warning  
The default behavior of Cache Rules is different from Page Rules. Refer to [Key differences](#key-differences) for more information.
2. Turn off your existing Page Rule and validate the behavior of the cache rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                    | Migrate to a cache rule                                                                                                                                               |
| ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with the 'Custom Cache Key' setting](https://developers.cloudflare.com/_astro/pr-custom-cache-key.B4mIYhPL_ZxFokH.webp) | ![Cache rule matching the 'Custom Cache Key' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-custom-cache-key-new.Cgx92M0b_1hvSHD.webp) |

### Migrate Disable Apps

* [ Dashboard ](#tab-panel-6022)
* [ Visual guide ](#tab-panel-6023)

**Context:**

You configured a Page Rule turning off Cloudflare Apps (deprecated) for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Disable Apps_

**How to migrate**:

1. [Create a configuration rule](https://developers.cloudflare.com/rules/configuration-rules/create-dashboard/) to disable Cloudflare Apps (deprecated) for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then the settings are**:  
         * **Setting**: Disable Apps
2. Turn off your existing Page Rule and validate the behavior of the configuration rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                       | Migrate to a configuration rule                                                                                                                                        |
| ------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Disable Apps' setting](https://developers.cloudflare.com/_astro/pr-disable-apps.DtWuKgu3_mB9kP.webp) | ![Configuration rule matching the 'Disable Apps' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-disable-apps-new.D0ZGFzGR_Z2cSCu2.webp) |

### Replace Disable Performance

Warning

The **Disable Performance** setting is deprecated. Any Page Rules with this setting will not be migrated.

This Page Rules setting turned off Polish and Rocket Loader. You can still turn on or off relevant Cloudflare features one by one using Configuration Rules.

* [ Dashboard ](#tab-panel-6024)
* [ Visual guide ](#tab-panel-6025)

**Context:**

You configured a Page Rule with **Disable Performance** (deprecated) for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Disable Performance_

**How to replace**:

1. [Create a configuration rule](https://developers.cloudflare.com/rules/configuration-rules/create-dashboard/) to disable Polish and Rocket Loader for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then the settings are**:  
         * **Polish**: _Off_  
         * **Rocket Loader**: Off
2. Turn off your existing Page Rule and validate the behavior of the configuration rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                     | Migrate to a configuration rule                                                                                                                                                               |
| -------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Disable Performance' setting](https://developers.cloudflare.com/_astro/pr-disable-performance.Q-fOmuUU_2xk0b.webp) | ![Configuration rule partially matching the 'Disable Performance' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-disable-performance-new.DL9beJ7__2cPCxI.webp) |

### Replace Disable Security

Warning

The **Disable Security** setting is deprecated. Any Page Rules with this setting will not be migrated.

This Page Rules setting turns off Email Obfuscation, Rate Limiting (previous version), Scrape Shield, URL (Zone) Lockdown, and WAF managed rules (previous version). You can still turn on or off relevant Cloudflare features one by one using Configuration Rules and WAF custom rules.

* [ Dashboard ](#tab-panel-6015)

**Context:**

You configured a Page Rule with **Disable Security** (deprecated) for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Disable Security_

This setting turned off a subset of Cloudflare security features: Email Obfuscation, Rate Limiting (previous version), Scrape Shield, URL (Zone) Lockdown, and WAF managed rules (previous version).

**How to replace**:

1. [Create a configuration rule](https://developers.cloudflare.com/rules/configuration-rules/create-dashboard/) to turn off one or more security features:  
   * [Email Obfuscation](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/)  
   * [Hotlink Protection](https://developers.cloudflare.com/waf/tools/scrape-shield/hotlink-protection/)
2. If required, [create a WAF exception](https://developers.cloudflare.com/waf/managed-rules/waf-exceptions/define-dashboard/) to skip one or more rules of WAF managed rulesets for requests coming from IP addresses in an allowlist.
3. Turn off your existing Page Rule and validate the behavior of the rules you created.
4. If your tests succeed, delete the existing Page Rule.

Warning

If you are still using [WAF managed rules (previous version)](https://developers.cloudflare.com/waf/reference/legacy/old-waf-managed-rules/) or [Rate Limiting (previous version)](https://developers.cloudflare.com/waf/reference/legacy/old-rate-limiting/), consider upgrading to the new versions of these products. It is not possible to turn off these older products using modern Rules features.

### Migrate Disable Zaraz

* [ Dashboard ](#tab-panel-6026)
* [ Visual guide ](#tab-panel-6027)

**Context:**

You configured a Page Rule turning off [Zaraz](https://developers.cloudflare.com/zaraz/) for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Disable Zaraz_

**How to migrate**:

1. [Create a configuration rule](https://developers.cloudflare.com/rules/configuration-rules/create-dashboard/) to turn off Zaraz for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then the settings are**:  
         * **Setting**: Disable Zaraz
2. Turn off your existing Page Rule and validate the behavior of the configuration rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                           | Migrate to a configuration rule                                                                                                                                         |
| ---------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Disable Zaraz' setting](https://developers.cloudflare.com/_astro/pr-disable-zaraz.BO7qA0TE_Z1JU8so.webp) | ![Configuration rule matching the 'Disable Zaraz' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-disable-zaraz-new.Cc92OsIN_1gBdti.webp) |

### Migrate Edge Cache TTL

* [ Dashboard ](#tab-panel-6064)
* [ Visual guide ](#tab-panel-6065)

**Context:**

You configured a Page Rule adjusting Edge Cache TTL for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Edge Cache TTL_
* **Enter Edge Cache TTL**: _a day_

**How to migrate**:

1. [Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to adjust edge cache TTL for caching resources on Cloudflare edge to one day, for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then**:  
         * **Cache eligibility**: Eligible for cache  
         * **Setting**: Edge TTL  
                  * Ignore cache-control header and use this TTL  
                  * **Input time-to-live (TTL)**: _1 day_  
Warning  
The default behavior of Cache Rules is different from Page Rules. Refer to [Key differences](#key-differences) for more information.
2. Turn off your existing Page Rule and validate the behavior of the cache rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                | Migrate to a cache rule                                                                                                                                          |
| --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with the 'Edge Cache TTL' setting](https://developers.cloudflare.com/_astro/pr-edge-cache-ttl.DdpuJjjM_1nFprQ.webp) | ![Cache rule matching the 'Edge Cache TTL' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-edge-cache-ttl-new.CASDurRT_DBFBY.webp) |

### Migrate Email Obfuscation

* [ Dashboard ](#tab-panel-6028)
* [ Visual guide ](#tab-panel-6029)

**Context:**

You configured a Page Rule turning off [Email Obfuscation](https://developers.cloudflare.com/waf/tools/scrape-shield/email-address-obfuscation/) for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Email Obfuscation_
* **Value**: Off

**How to migrate**:

1. [Create a configuration rule](https://developers.cloudflare.com/rules/configuration-rules/create-dashboard/) to turn off Email Obfuscation for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then the settings are**:  
         * **Setting**: Email Obfuscation  
                  * **Value**: Off
2. Turn off your existing Page Rule and validate the behavior of the configuration rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                  | Migrate to a configuration rule                                                                                                                                                       |
| ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Email Obfuscation' setting](https://developers.cloudflare.com/_astro/pr-email-obfuscation.B5bsi7dl_ZmPA2p.webp) | ![Configuration rule matching the 'Email Obfuscation > Off' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-email-obfuscation-new.CV0JNmIj_1a6Vq6.webp) |

### Migrate Forwarding URL

**Example #1: Redirect `www` to root domain**

* [ Dashboard ](#tab-panel-6074)
* [ Visual guide ](#tab-panel-6075)

**Context:**

You configured a Page Rule permanently redirecting `www.example.com` to `example.com` on all URI paths:

* **URL**: `www.example.com/*`
* **Setting**: _Forwarding URL_
* **Select Status code**: _301 - Permanent Redirect_
* **Destination URL**: `https://example.com/$1`

**How to migrate**:

1. [Create a single redirect](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/create-dashboard/) to permanently redirect requests from `https://www.example.com` to `https://example.com`. You can select the **Redirect from WWW to Root** rule template or enter the following rule configuration:  
   * **If incoming requests match**: Wildcard pattern  
         * **Request URL**: `https://www.example.com/*`  
   * **Then**:  
         * **Target URL**: `https://example.com/${1}`  
         * **Status code**: _301_  
         * **Preserve query string**: Enabled
2. Turn off your existing Page Rule and validate the behavior of the redirect you created.
3. If your tests succeed, delete the existing Page Rule.

Notes about the rule equivalence

The provided example using Single Redirects is not an exact match for the previously existing Page Rule in the same example.

The exact equivalent would need to match both HTTP and HTTPS incoming requests, which you could achieve using a wildcard pattern like the following (notice the extra `*` after `http`):

* **Request URL**: `http*://www.example.com/*`

This would require you to also change the **Target URL** to use the second wildcard capture group instead of the first one (corresponding to the text captured by second `*` in the wildcard pattern above):

* **Target URL**: `https://example.com/${2}`

| Page Rules configuration                                                                                                                | Migrate to a single redirect                                                                                                                                              |
| --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule #1 with 'Forwarding URL' setting](https://developers.cloudflare.com/_astro/pr-forwarding-url.DyV2zs8N_Z1PQuiN.webp) | ![Single redirect matching the 'Forwarding URL' setting of the example Page Rule #1](https://developers.cloudflare.com/_astro/pr-forwarding-url-new.FfZIMpof_ZfVgYH.webp) |

**Example #2: Redirect all pages under old path to new path**

* [ Dashboard ](#tab-panel-6076)
* [ Visual guide ](#tab-panel-6077)

**Context:**

You configured a Page Rule permanently redirecting `example.com/old-path` to `example.com/new-path`:

* **URL**: `example.com/old-path/*`
* **Setting**: _Forwarding URL_
* **Select Status code**: _301 - Permanent Redirect_
* **Destination URL**: `https://example.com/new-path/$1`

**How to migrate**:

1. [Create a single redirect](https://developers.cloudflare.com/rules/url-forwarding/single-redirects/create-dashboard/) to permanently redirect requests for `example.com/old-path` to `example.com/new-path`:  
   * **If incoming requests match**: Wildcard pattern  
         * **Request URL**: `https://example.com/old-path/*`  
   * **Then**:  
         * **Target URL**: `https://example.com/new-path/${1}`  
         * **Status code**: _301_  
         * **Preserve query string**: Enabled
2. Turn off your existing Page Rule and validate the behavior of the redirect you created.
3. If your tests succeed, delete the existing Page Rule.

Notes about the rule equivalence

The provided example using Single Redirects is not an exact match for the previously existing Page Rule in the same example.

The exact equivalent would need to match both HTTP and HTTPS incoming requests, which you could achieve using a wildcard pattern like the following (notice the extra `*` after `http`):

* **Request URL**: `http*://example.com/old-path/*`

This would require you to also change the **Target URL** to use the second wildcard capture group instead of the first one (corresponding to the text captured by second `*` in the wildcard pattern above):

* **Target URL**: `https://example.com/new-path/${2}`

| Page Rules configuration                                                                                                                 | Migrate to a single redirect                                                                                                                                               |
| ---------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule #2 with 'Forwarding URL' setting](https://developers.cloudflare.com/_astro/pr-forwarding-url-2.CNt6YZ_U_ZJCQKH.webp) | ![Single redirect matching the 'Forwarding URL' setting of the example Page Rule #2](https://developers.cloudflare.com/_astro/pr-forwarding-url-2-new.CP3zl46U_W8inj.webp) |

### Migrate Host Header Override

* [ Dashboard ](#tab-panel-6030)
* [ Visual guide ](#tab-panel-6031)

**Context:**

You configured a Page Rule changing the `Host` HTTP header to `example.saas-provider.com`, for all requests addressed at any subdomain of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Host Header Override_
* **Enter value**: `example.saas-provider.com`

**How to migrate**:

1. [Create an origin rule](https://developers.cloudflare.com/rules/origin-rules/create-dashboard/) changing the `Host` header to `example.saas-provider.com` for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then**:  
         * **Set origin parameters**:  
                  * **Host Header** \> **Rewrite to**: `example.saas-provider.com`
2. Turn off your existing Page Rule and validate the behavior of the origin rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                         | Migrate to an origin rule                                                                                                                                                       |
| ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Host Header Override' setting](https://developers.cloudflare.com/_astro/pr-host-header-override.BXq8XNIs_Z2j1cOS.webp) | ![Origin rule matching the 'Host Header Override' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-host-header-override-new.DUASGBHN_Z2fFGfr.webp) |

### Migrate IP Geolocation Header

* [ Dashboard ](#tab-panel-6032)
* [ Visual guide ](#tab-panel-6033)

**Context:**

You configured a Page Rule adding a `CF-IPCountry` HTTP header, for all requests addressed at any subdomain of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _IP Geolocation Header_
* **Value**: On

**How to migrate**:

1. [Turn on the **Add visitor location headers** Managed Transform](https://developers.cloudflare.com/rules/transform/managed-transforms/configure/) — a Transform Rules feature — to add the `CF-IPCountry` and other location headers to all requests.
2. Turn off your existing Page Rule and validate the behavior of the Managed Transform.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                           | Migrate to a Managed Transform                                                                                                                                                                                             |
| -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'IP Geolocation Header' setting](https://developers.cloudflare.com/_astro/pr-ip-geolocation-header._es904nB_Z1kVGHd.webp) | ![The 'Add visitor location headers' Managed Transform matching the 'IP Geolocation Header' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-ip-geolocation-header-new.D3CE9V7z_Z22BvhB.webp) |

### Migrate Opportunistic Encryption

* [ Dashboard ](#tab-panel-6034)
* [ Visual guide ](#tab-panel-6035)

**Context:**

You configured a Page Rule turning off Opportunistic Encryption for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Opportunistic Encryption_
* **Value**: Off

**How to migrate**:

1. [Create a configuration rule](https://developers.cloudflare.com/rules/configuration-rules/create-dashboard/) to turn off Opportunistic Encryption for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then the settings are**:  
         * **Setting**: Opportunistic Encryption  
                  * **Value**: Off
2. Turn off your existing Page Rule and validate the behavior of the configuration rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                                | Migrate to a configuration rule                                                                                                                                                                      |
| ------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Opportunistic Encryption' setting](https://developers.cloudflare.com/_astro/pr-opportunistic-encryption.BcbwaI0m_2qECYg.webp) | ![Configuration rule matching the 'Opportunistic Encryption > Off' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-opportunistic-encryption-new.LwpNCqst_Z235yOw.webp) |

### Migrate Origin Cache Control

* [ Dashboard ](#tab-panel-6066)
* [ Visual guide ](#tab-panel-6067)

**Context:**

You configured a Page Rule turning off Origin Cache Control for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: Origin Cache Control
* **Value**: Off

**How to migrate**:

1. [Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to determine edge cache behavior for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then**:  
         * **Cache eligibility**: Eligible for cache  
         * **Setting**: Origin Cache Control  
                  * **Enable Origin Cache Control**: Off  
Warning  
The default behavior of Cache Rules is different from Page Rules. Refer to [Key differences](#key-differences) for more information.
2. Turn off your existing Page Rule and validate the behavior of the cache rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                         | Migrate to a cache rule                                                                                                                                                       |
| ------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Origin Cache Control' setting](https://developers.cloudflare.com/_astro/pr-origin-cache-control.DCUWJE-U_Z2k59Gp.webp) | ![Cache rule matching the 'Origin Cache Control' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-origin-cache-control-new.DqpXz-FD_ZDbSey.webp) |

### Migrate Origin Error Page Pass-thru

* [ Dashboard ](#tab-panel-6068)
* [ Visual guide ](#tab-panel-6069)

**Context:**

You configured a Page Rule turning on Origin Error Page Pass-thru for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Origin Error Page Pass-thru_
* **Value**: On

**How to migrate**:

1. [Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to determine edge cache behavior for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then**:  
         * **Cache eligibility**: Eligible for cache  
         * **Setting**: Origin error page pass-thru  
                  * **Use Origin error page pass-thru**: On  
Warning  
The default behavior of Cache Rules is different from Page Rules. Refer to [Key differences](#key-differences) for more information.
2. Turn off your existing Page Rule and validate the behavior of the cache rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                                      | Migrate to a cache rule                                                                                                                                                                         |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Origin Error Page Pass-thru' setting](https://developers.cloudflare.com/_astro/pr-origin-error-page-pass-thru.CaO5dguv_ZTxuQ5.webp) | ![Cache rule matching the 'Origin Error Page Pass-thru > On' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-origin-error-page-pass-thru-new.CEumhpfw_ARQAy.webp) |

### Migrate Polish

* [ Dashboard ](#tab-panel-6036)
* [ Visual guide ](#tab-panel-6037)

**Context:**

You configured a Page Rule turning off [Polish](https://developers.cloudflare.com/images/polish/) for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: Polish
* **Value**: Off

**How to migrate**:

1. [Create a configuration rule](https://developers.cloudflare.com/rules/configuration-rules/create-dashboard/) to turn off Polish for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then the settings are**:  
         * **Setting**: Polish  
                  * **Select value**: _Off_
2. Turn off your existing Page Rule and validate the behavior of the configuration rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                             | Migrate to a configuration rule                                                                                                                                  |
| -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Polish' setting](https://developers.cloudflare.com/_astro/pr-polish.BMjezHuI_Z2nbLxT.webp) | ![Configuration rule matching the 'Polish > Off' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-polish-new.BPVnKGv2_Z1vqj8p.webp) |

### Migrate Query String Sort

* [ Dashboard ](#tab-panel-6070)
* [ Visual guide ](#tab-panel-6071)

**Context:**

You configured a Page Rule turning on Query String Sort for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Query String Sort_
* **Value**: On

**How to migrate**:

1. [Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to sort query string parameters for caching purposes, for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then**:  
         * **Cache eligibility**: Eligible for cache  
         * **Setting**: Cache key  
                  * **Sort query string**: On  
Warning  
The default behavior of Cache Rules is different from Page Rules. Refer to [Key differences](#key-differences) for more information.
2. Turn off your existing Page Rule and validate the behavior of the cache rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                   | Migrate to a cache rule                                                                                                                                                       |
| ------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Query String Sort' setting](https://developers.cloudflare.com/_astro/pr-query-string-sort.C01G9KtA_Z1y5BVz.webp) | ![Cache rule matching the 'Query String Sort > On' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-query-string-sort-new.DhEB-zV8_Z1HxHes.webp) |

### Migrate Resolve Override

* [ Dashboard ](#tab-panel-6038)
* [ Visual guide ](#tab-panel-6039)

**Context:**

You configured a Page Rule changing the origin to `example.saas-provider.com`, for all requests addressed at any subdomain of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Resolve Override_
* **Enter value**: `example.saas-provider.com`

**How to migrate**:

1. [Create an origin rule](https://developers.cloudflare.com/rules/origin-rules/create-dashboard/) overriding the origin to `example.saas-provider.com` for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then**:  
         * **DNS Record** \> **Override to**: `example.saas-provider.com`
2. Turn off your existing Page Rule and validate the behavior of the origin rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                | Migrate to an origin rule                                                                                                                                              |
| --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Resolve Override' setting](https://developers.cloudflare.com/_astro/pr-resolve-override.B4LoxPLL_1wNJPY.webp) | ![Origin rule matching the 'Resolve Override' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-resolve-override-new.CqsoTaU3_ZEBJqh.webp) |

### Migrate Respect Strong ETags

* [ Dashboard ](#tab-panel-6072)
* [ Visual guide ](#tab-panel-6073)

**Context:**

You configured a Page Rule turning on byte-for-byte equivalency checks for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Respect Strong ETags_
* **Value**: On

**How to migrate**:

1. [Create a cache rule](https://developers.cloudflare.com/cache/how-to/cache-rules/create-dashboard/) to respect strong ETags for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then**:  
         * **Cache eligibility**: Eligible for cache  
         * **Setting**: Respect strong ETags  
                  * **Use strong ETag headers**: On  
Warning  
The default behavior of Cache Rules is different from Page Rules. Refer to [Key differences](#key-differences) for more information.
2. Turn off your existing Page Rule and validate the behavior of the cache rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                        | Migrate to a cache rule                                                                                                                                                             |
| ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Respect Strong ETags' setting](https://developers.cloudflare.com/_astro/pr-respect-strong-etags.CUOv_EvP_Z3LXqt.webp) | ![Cache rule matching the 'Respect Strong ETags > On' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-respect-strong-etags-new.BnNZFkL6_Z1oczSf.webp) |

### Migrate Rocket Loader

* [ Dashboard ](#tab-panel-6040)
* [ Visual guide ](#tab-panel-6041)

**Context:**

You configured a Page Rule turning off Rocket Loader for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Rocket Loader_
* **Value**: Off

**How to migrate**:

1. [Create a configuration rule](https://developers.cloudflare.com/rules/configuration-rules/create-dashboard/) to turn off Rocket Loader for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then the settings are**:  
         * **Setting**: Rocket Loader  
                  * **Value**: Off
2. Turn off your existing Page Rule and validate the behavior of the configuration rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                          | Migrate to a configuration rule                                                                                                                                              |
| --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Rocket Loader' setting](https://developers.cloudflare.com/_astro/pr-rocket-loader.DOfWWA3Z_1LhMmq.webp) | ![Configuration rule matching the 'Rocket Loader > Off' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-rocket-loader-new.CPlD3EdY_PllsY.webp) |

### Migrate Security Level

* [ Dashboard ](#tab-panel-6042)
* [ Visual guide ](#tab-panel-6043)

**Context:**

You configured a Page Rule setting Security Level to _I'm Under Attack_ for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _Security Level_
* **Select Security Level**: _I'm Under Attack_

**How to migrate**:

1. [Create a configuration rule](https://developers.cloudflare.com/rules/configuration-rules/create-dashboard/) to set Security Level to _I'm Under Attack_, for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then the settings are**:  
         * **Setting**: I'm Under Attack  
         * **Value**: On
2. Turn off your existing Page Rule and validate the behavior of the configuration rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                             | Migrate to a configuration rule                                                                                                                                                              |
| ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'Security Level' setting](https://developers.cloudflare.com/_astro/pr-security-level.YzQR-68G_Z1bMy81.webp) | ![Configuration rule matching the "Security Level > I'm Under Attack" setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-security-level-new.DP1C5HJ8_1BGLyi.webp) |

### Migrate True Client IP Header

* [ Dashboard ](#tab-panel-6044)
* [ Visual guide ](#tab-panel-6045)

**Context:**

You configured a Page Rule adding a `True-Client-IP` HTTP header for all requests addressed at any subdomain of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _True Client IP Header_
* **Value**: On

**How to migrate**:

1. [Turn on the **Add "True-Client-IP" header** Managed Transform](https://developers.cloudflare.com/rules/transform/managed-transforms/configure/) — a Transform Rules feature — to add the `True-Client-IP` header to all requests.
2. Turn off your existing Page Rule and validate the behavior of the Managed Transform.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                                                         | Migrate to a Managed Transform                                                                                                                                                                                            |
| ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'True Client IP Header' setting](https://developers.cloudflare.com/_astro/pr-true-client-ip-header.h51QIhp7_7UCm4.webp) | ![The 'Add "True-Client-IP" header' Managed Transform matching the 'True Client IP Header' setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-true-client-ip-header-new.DKFw6CYO_Z1SyD08.webp) |

### Migrate SSL

* [ Dashboard ](#tab-panel-6046)
* [ Visual guide ](#tab-panel-6047)

**Context:**

You configured a Page Rule setting SSL to _Strict_ for all subdomains of `example.com` and the `example.com` domain itself:

* **URL**: `*example.com/*`
* **Setting**: _SSL_
* **Select SSL/TLS encryption mode**: _Strict_

**How to migrate**:

1. [Create a configuration rule](https://developers.cloudflare.com/rules/configuration-rules/create-dashboard/) to set SSL to _Strict_, for any hostname containing `example.com`:  
   * **When incoming requests match**: Custom filter expression  
         * Using the Expression Builder:  
         `Hostname contains "example.com"`  
         * Using the Expression Editor:  
         `(http.host contains "example.com")`  
   * **Then the settings are**:  
         * **Setting**: SSL  
                  * **Select SSL/TLS encryption mode**: _Strict_
2. Turn off your existing Page Rule and validate the behavior of the configuration rule you created.
3. If your tests succeed, delete the existing Page Rule.

| Page Rules configuration                                                                                      | Migrate to a configuration rule                                                                                                                     |
| ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| ![Example Page Rule with 'SSL' setting](https://developers.cloudflare.com/_astro/pr-ssl.pGEGjIS-_ZBAt4W.webp) | ![Configuration rule matching the "SSL" setting of the example Page Rule](https://developers.cloudflare.com/_astro/pr-ssl-new.DjFLYHwZ_1IeMdx.webp) |

## Settings that will not be migrated

The following Page Rules settings will not be migrated to other types of rules:

* **Disable Performance** (this setting is deprecated)
* **Disable Railgun** (this setting is deprecated, since Railgun is no longer available)
* **Disable Security** (this setting is deprecated)
* **Response Buffering** (this setting is deprecated)
* **Web Application Firewall** (this setting is deprecated, since the previous version of WAF managed rules is deprecated)

All other Page Rules settings will be migrated during 2025.

## More resources

If you have feedback to share, refer to our [Community thread ↗](https://community.cloudflare.com/t/important-page-rules-deprecation/656021).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/reference/","name":"Reference"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/reference/page-rules-migration/","name":"Page Rules migration guide"}}]}
```

---

---
title: Troubleshoot Rules
description: Review common troubleshooting scenarios for Rules features.
image: https://developers.cloudflare.com/core-services-preview.png
---

[Skip to content](#%5Ftop) 

Was this helpful?

YesNo

[ Edit page ](https://github.com/cloudflare/cloudflare-docs/edit/production/src/content/docs/rules/reference/troubleshooting.mdx) [ Report issue ](https://github.com/cloudflare/cloudflare-docs/issues/new/choose) 

Copy page

# Troubleshoot Rules

## Interaction between redirects and other Cloudflare products

Your redirects may interfere with Cloudflare products and features such as challenges. Consider excluding the [/cdn-cgi/\* URI path](https://developers.cloudflare.com/fundamentals/reference/cdn-cgi-endpoint/) in your rule expression to avoid issues. Alternatively, you may exclude only a sub-path such as `/cdn-cgi/challenge-platform/*` to avoid issues with specific features (in this example, [Cloudflare challenges](#interaction-between-cloudflare-challenges-and-rules-features)).

You may also want to exclude the `/.well-known/*` URL path used by several validation services. Refer to [Interaction between redirects and verification procedures like HTTP DCV](#interaction-between-redirects-and-verification-procedures-like-http-dcv) for more information.

## Interaction between Cloudflare challenges and Rules features

If you are issuing a [challenge](https://developers.cloudflare.com/cloudflare-challenges/) for a given URI path that has one or more Rules features enabled, you should exclude URI paths starting with `/cdn-cgi/challenge-platform/` in your rule expressions to avoid challenge loops.

For example, define a compound expression for your rule using the `and` operator and the [starts\_with()](https://developers.cloudflare.com/ruleset-engine/rules-language/functions/#starts%5Fwith) function:

```

<OTHER_RULE_CONDITIONS> and not starts_with(http.request.uri, "/cdn-cgi/challenge-platform/")


```

## Interaction between redirects and verification procedures like HTTP DCV

Paths used in validation procedures such as custom hostname verification ([Cloudflare for SaaS](https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/)), [Pages domain validation](https://developers.cloudflare.com/pages/configuration/debugging-pages/), or [HTTP domain control validation (DCV)](https://developers.cloudflare.com/ssl/edge-certificates/changing-dcv-method/methods/http/) may be affected by redirects.

Consider excluding the `/.well-known/*` URI path from your rule to avoid issues.

## Content-Length header removed from response

Cloudflare may remove the `Content-Length` header from responses delivered to website visitors. If the visitor must receive the `Content-Length` header, configure the origin server to include a `cache-control: no-transform` HTTP header in the response.

## This rule may not apply to your traffic

If your rule expression is matching a hostname for which you have neither created a DNS record nor enabled proxying traffic through Cloudflare, you will get a pop-up window with a couple of options:

* **If no DNS record exists for the hostname**: Whether to proceed with the rule creation or to create a new proxied DNS record for that hostname.
* **If there is a DNS record for the hostname, but traffic is not being proxied**: Whether to proceed with the rule creation or to enable proxying for the existing DNS record.

If you choose to create a new DNS record, the new record will have a `rules` tag and the following associated comment:

```

Created during Cloudflare Rules deployment process for <RULE_NAME>


```

## URL rewrites affect other Rules features executed later

If you rewrite a URI path using a [URL rewrite](https://developers.cloudflare.com/rules/transform/url-rewrite/), this may affect other Rules features executed later — such as [Origin Rules](https://developers.cloudflare.com/rules/origin-rules/) — if they include the URI path in their filter expression.

Consider the following origin rule configuration:

* Rule expression: `http.host == "example.com" and starts_with(http.request.uri.path, "/downloads/")`
* **Host header** \> **Rewrite to**: `assets.example.com`

If you configure a new URL rewrite with the following configuration:

* Rule expression: `http.host == "example.com" and starts_with(http.request.uri.path, "/downloads/")`
* **Path** \> **Rewrite to** \> **Dynamic**: `regex_replace(http.request.uri.path, "^/downloads/", "/")`

The origin rule will no longer match `/downloads/*` paths, since URL rewrites run before Origin Rules and the URI path will be rewritten from `"/downloads/"` to `"/"`.

### Solution

To prevent this situation, use raw fields in your rule expression. Raw fields are immutable during the entire request evaluation workflow, and they are not affected by the actions of previously matched rules.

In the current example, you could use the `raw.http.request.uri.path` field in both rules:

**URL rewrite**

* Rule expression: `http.host == "example.com" and starts_with(raw.http.request.uri.path, "/downloads/")`
* **Path** \> **Rewrite to** \> **Dynamic**: `regex_replace(raw.http.request.uri.path, "^/downloads/", "/")`

**Origin rule**

* Rule expression: `http.host == "example.com" and starts_with(raw.http.request.uri.path, "/downloads/")`
* **Host header** \> **Rewrite to**: `assets.example.com`

This way, the two rules will work as intended. Additionally, this allows you to use the same expression in the two rules, even when the first rule is updating the URI path value.

For a list of raw fields, refer to the [Fields reference](https://developers.cloudflare.com/ruleset-engine/rules-language/fields/reference/?field-category=Raw+fields).

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/rules/","name":"Rules"}},{"@type":"ListItem","position":3,"item":{"@id":"/rules/reference/","name":"Reference"}},{"@type":"ListItem","position":4,"item":{"@id":"/rules/reference/troubleshooting/","name":"Troubleshoot Rules"}}]}
```
