From b5296a7523206d8bc88288915c9c5a6963a1932e Mon Sep 17 00:00:00 2001 From: Nicolas Gayerie Date: Wed, 24 Jun 2026 13:29:01 +0000 Subject: [PATCH 1/2] Add Rules documentation updates Document undocumented behaviors and configuration guidance across Rules, ruleset engine, custom errors, and bulk redirects: 1. http.host always raw, even with Origin Rules host override 3. Custom Error Rules vs default WAF block page distinction 4. Custom error asset size limit (1.5 MB after base64 inlining) 5. Bulk Redirects execution order relative to WAF 6. X-Real-IP and other protected headers via Snippets/Workers subrequest 7. x-forwarded-for re-added by Cloudflare backend proxy after rule phases 11. Maximum 64 regular expressions per rule expression 12. Preserve query string overwrites target URL query string Resolves DEE-3644 --- src/content/docs/rules/custom-errors/index.mdx | 8 +++++++- .../transform/request-header-modification/index.mdx | 4 ++-- .../rules/url-forwarding/bulk-redirects/index.mdx | 11 +++++++++++ .../bulk-redirects/reference/parameters.mdx | 4 ++++ .../rules-language/expressions/index.mdx | 6 ++++++ src/content/fields/index.yaml | 4 ++-- 6 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/content/docs/rules/custom-errors/index.mdx b/src/content/docs/rules/custom-errors/index.mdx index acb3c42800d..ddf8a99973c 100644 --- a/src/content/docs/rules/custom-errors/index.mdx +++ b/src/content/docs/rules/custom-errors/index.mdx @@ -40,7 +40,7 @@ When an error of a [specific type](/rules/custom-errors/reference/error-page-typ :::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](/waf/custom-rules/create-dashboard/#configure-a-custom-response-for-blocked-requests) takes precedence over an Error Page and custom error rules. +To customize a challenge page or the default Cloudflare WAF block page, use an Error Page. Custom Error Rules do not apply to security actions originating from Cloudflare products (such as the default WAF block page) — they only override error responses from your origin server or [custom WAF responses](/waf/custom-rules/create-dashboard/#configure-a-custom-response-for-blocked-requests). A custom WAF response configured directly in a WAF rule action takes precedence over both an Error Page and a Custom Error Rule. ::: ## Availability @@ -88,3 +88,9 @@ A custom error asset corresponds to a web resource such as an HTML web page (inc 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). + +## Size limits + +When you provide a URL for a [custom error asset](#custom-error-assets), Cloudflare fetches the page and inlines all referenced resources (images, CSS, and JavaScript) into the HTML using base64 encoding. The processed page must not exceed approximately 1.5 MB. + +If your custom error asset exceeds this size, reduce the number or size of referenced resources. You can also host large resources externally, as long as they remain accessible from Cloudflare's network when the asset is fetched. diff --git a/src/content/docs/rules/transform/request-header-modification/index.mdx b/src/content/docs/rules/transform/request-header-modification/index.mdx index 116d2c614ea..d8e4021869e 100644 --- a/src/content/docs/rules/transform/request-header-modification/index.mdx +++ b/src/content/docs/rules/transform/request-header-modification/index.mdx @@ -59,9 +59,9 @@ You can create a request header transform rule [in the dashboard](/rules/transfo - Due to protocol compliance reasons, modifying or removing request headers with [forbidden header names](https://developer.mozilla.org/en-US/docs/Glossary/Forbidden_header_name) (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`. +- 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`. If you need to set a protected header such as `x-real-ip` on requests reaching your origin server, use [Cloudflare Snippets](/rules/snippets/) or [Cloudflare Workers](/workers/) with a subrequest (`fetch(request)`) — the header can be set on subrequests but not on the parent request. -- Although you can remove the `x-forwarded-for` header, Cloudflare's cache service will add it back (with a different value) before the request reaches your origin server. However, if the request is handled by Cloudflare Workers — which [run before the cache](/workers/reference/how-the-cache-works/) — the `x-forwarded-for` request header will be absent because the cache service has not yet re-added it. +- Although you can remove the `x-forwarded-for` header in a Request Header Transform Rule, Cloudflare's backend proxy re-adds it (with the visitor's IP address) before the request reaches your origin server, because the proxy runs after all rule phases. The same applies to [Managed Transforms](/rules/transform/managed-transforms/). However, if the request is handled by Cloudflare Workers — which [run before the cache](/workers/reference/how-the-cache-works/) — the `x-forwarded-for` request header will be absent because the proxy has not yet re-added it. - 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. diff --git a/src/content/docs/rules/url-forwarding/bulk-redirects/index.mdx b/src/content/docs/rules/url-forwarding/bulk-redirects/index.mdx index d3b33b51e84..cb6e72b6be2 100644 --- a/src/content/docs/rules/url-forwarding/bulk-redirects/index.mdx +++ b/src/content/docs/rules/url-forwarding/bulk-redirects/index.mdx @@ -27,6 +27,17 @@ Unlike dynamic URL redirects created in [Single Redirects](/rules/url-forwarding --- +## Bulk Redirects and the WAF + +Bulk Redirects run after the WAF in the request processing pipeline. This means that: + +- If a [WAF custom rule](/waf/custom-rules/) or [rate limiting rule](/waf/rate-limiting-rules/) blocks a request, the Bulk Redirect will not execute. +- If a WAF rule logs or challenges a request that subsequently passes, the firewall event will still appear in [Security Events](/waf/analytics/security-events/) and [Logpush](/logs/) — even though the request is later redirected. This is expected behavior. + +For the complete request processing order, refer to [Rules execution order](/rules/url-forwarding/#execution-order). + +--- + ## Related resources - [Availability](/rules/url-forwarding/#availability): Information on the Bulk Redirects quotas and features per Cloudflare plan. diff --git a/src/content/docs/rules/url-forwarding/bulk-redirects/reference/parameters.mdx b/src/content/docs/rules/url-forwarding/bulk-redirects/reference/parameters.mdx index ef7db4e357b..c410388a576 100644 --- a/src/content/docs/rules/url-forwarding/bulk-redirects/reference/parameters.mdx +++ b/src/content/docs/rules/url-forwarding/bulk-redirects/reference/parameters.mdx @@ -65,6 +65,10 @@ 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/`. +:::caution +When **Preserve query string** is enabled and the target URL also contains a query string, the original request's query string replaces the target URL's query string entirely. To add a fixed query parameter to redirected URLs, leave **Preserve query string** disabled and include the parameter directly in the target URL. +::: + ## Preserve path suffix API field: `preserve_path_suffix` diff --git a/src/content/docs/ruleset-engine/rules-language/expressions/index.mdx b/src/content/docs/ruleset-engine/rules-language/expressions/index.mdx index fef6f9a2b4c..9f65e370b4b 100644 --- a/src/content/docs/ruleset-engine/rules-language/expressions/index.mdx +++ b/src/content/docs/ruleset-engine/rules-language/expressions/index.mdx @@ -61,6 +61,12 @@ Compound expressions allow you to generate sophisticated, highly targeted rules. This limit applies whether you use the visual [Expression Builder](/ruleset-engine/rules-language/expressions/edit-expressions/#expression-builder) to define your expression, or write the expression manually in the [Expression Editor](/ruleset-engine/rules-language/expressions/edit-expressions/#expression-editor). +## Maximum regular expressions per rule + +Each rule can contain a maximum of 64 regular expressions in its expression. This limit applies across all rule types that use the [Rules language](/ruleset-engine/rules-language/). + +Rules that exceed this limit cannot be created or updated. Existing rules above this limit continue to work but cannot be modified until the expression is simplified. + ## Additional features You can also use the following Rules language features in your expressions: diff --git a/src/content/fields/index.yaml b/src/content/fields/index.yaml index 6787387e894..55805b4e4b7 100644 --- a/src/content/fields/index.yaml +++ b/src/content/fields/index.yaml @@ -13,9 +13,9 @@ entries: keywords: [request, uri, url, domain, client, visitor] summary: The hostname used in the full request URI. description: |- - The `http.host` field contains the `Host` header from the original request. + The `http.host` field contains the `Host` header from the original client request. - If you have configured [Origin Rules](/rules/origin-rules/) that change the hostname, they will not be reflected in the `http.host` field value. + If you have configured [Origin Rules](/rules/origin-rules/) that change the hostname, this change is not reflected in the `http.host` value seen by other rule phases (such as custom rules, cache rules, or transform rules), [Cloudflare Workers](/workers/), or the [`request.cf`](/workers/runtime-apis/request/#incomingrequestcfproperties) object. All rule phases and Workers evaluate against the original, unmodified host. example_value: |- "www.example.org" From af77a26c7d786804473e9778571cf6166fe773b2 Mon Sep 17 00:00:00 2001 From: Nicolas Gayerie Date: Wed, 24 Jun 2026 15:03:48 +0000 Subject: [PATCH 2/2] Address ask-bonk review feedback - http.host: drop misleading request.cf reference (it holds metadata like colo/country, not the host header) - custom-errors: nest 'Size limits' as H3 under 'Custom Error Assets' (the limit is asset-specific, not page-wide) - custom-errors: align casing ('custom error rule' lowercase to match the rest of the page) --- src/content/docs/rules/custom-errors/index.mdx | 6 +++--- src/content/fields/index.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/content/docs/rules/custom-errors/index.mdx b/src/content/docs/rules/custom-errors/index.mdx index ddf8a99973c..57bf5eb3573 100644 --- a/src/content/docs/rules/custom-errors/index.mdx +++ b/src/content/docs/rules/custom-errors/index.mdx @@ -40,7 +40,7 @@ When an error of a [specific type](/rules/custom-errors/reference/error-page-typ :::note -To customize a challenge page or the default Cloudflare WAF block page, use an Error Page. Custom Error Rules do not apply to security actions originating from Cloudflare products (such as the default WAF block page) — they only override error responses from your origin server or [custom WAF responses](/waf/custom-rules/create-dashboard/#configure-a-custom-response-for-blocked-requests). A custom WAF response configured directly in a WAF rule action takes precedence over both an Error Page and a Custom Error Rule. +To customize a challenge page or the default Cloudflare WAF block page, use an Error Page. Custom Error Rules do not apply to security actions originating from Cloudflare products (such as the default WAF block page) — they only override error responses from your origin server or [custom WAF responses](/waf/custom-rules/create-dashboard/#configure-a-custom-response-for-blocked-requests). A custom WAF response configured directly in a WAF rule action takes precedence over both an Error Page and a custom error rule. ::: ## Availability @@ -89,8 +89,8 @@ Once the custom error asset is stored in Cloudflare's global network, the URL yo 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). -## Size limits +### Size limits -When you provide a URL for a [custom error asset](#custom-error-assets), Cloudflare fetches the page and inlines all referenced resources (images, CSS, and JavaScript) into the HTML using base64 encoding. The processed page must not exceed approximately 1.5 MB. +When you provide a URL for a custom error asset, Cloudflare fetches the page and inlines all referenced resources (images, CSS, and JavaScript) into the HTML using base64 encoding. The processed page must not exceed approximately 1.5 MB. If your custom error asset exceeds this size, reduce the number or size of referenced resources. You can also host large resources externally, as long as they remain accessible from Cloudflare's network when the asset is fetched. diff --git a/src/content/fields/index.yaml b/src/content/fields/index.yaml index 55805b4e4b7..5c88bf72004 100644 --- a/src/content/fields/index.yaml +++ b/src/content/fields/index.yaml @@ -15,7 +15,7 @@ entries: description: |- The `http.host` field contains the `Host` header from the original client request. - If you have configured [Origin Rules](/rules/origin-rules/) that change the hostname, this change is not reflected in the `http.host` value seen by other rule phases (such as custom rules, cache rules, or transform rules), [Cloudflare Workers](/workers/), or the [`request.cf`](/workers/runtime-apis/request/#incomingrequestcfproperties) object. All rule phases and Workers evaluate against the original, unmodified host. + If you have configured [Origin Rules](/rules/origin-rules/) that change the hostname, this change is not reflected in the `http.host` value seen by other rule phases (such as custom rules, cache rules, or transform rules) or [Cloudflare Workers](/workers/). All rule phases and Workers evaluate against the original, unmodified host. example_value: |- "www.example.org"