Skip to content

Changelog

New updates and improvements at Cloudflare.

Remove surrounding bytes with trim functions

Cloudflare Rules supports three new functions for removing surrounding bytes. Use them to remove whitespace before comparing request values. All HTTP products support these functions on all plans:

  • trim() removes bytes from both ends.
  • trim_start() removes bytes from the start.
  • trim_end() removes bytes from the end.

By default, these functions remove ASCII whitespace. An optional constant string specifies a custom set of bytes.

If the input value is nil, these functions return nil.

For example, this expression removes surrounding whitespace before comparing a header value:

trim(http.request.headers["x-label"][0]) eq "approved"

For details, refer to the trim(), trim_start(), and trim_end() function references.

Failed detections field available in Rules

You can now use cf.appsec.request.failed_detections to control how your rules handle requests when a security detection reports a failure.

The field is an Array<String> of detection IDs that reports failures from content scanning, WAF attack score, attack signature detection, leaked credentials detection, and AI prompt detections for personally identifiable information (PII), prompt injection, custom topics, and unsafe topics.

The field does not alter the existing behavior of detections. Use it in rules to choose how to handle requests with reported failures.

When no failures are reported, the field returns []. You can use it on all plans, but your plan must still include the detections and rule features you want to use.

Supported rules:

  • Custom rules at the zone and account levels
  • Rate limiting rules at the zone and account levels
  • Request Header Transform Rules at the zone level

Match any reported failure:

len(cf.appsec.request.failed_detections) gt 0

Match a reported leaked credentials detection failure:

any(cf.appsec.request.failed_detections[*] eq "waf_credential_check")

For more information, refer to the Failed detections field reference.

hash_in_range() is globally available for HTTP products

hash_in_range() is globally available for HTTP products on all plans. It hashes fields into an integer within a specified range. Use this result to select a portion of requests.

Use cf.random_seed to select approximately 10% of requests at random:

hash_in_range(0, 100, cf.random_seed) < 10

With Cloudflare for SaaS, use custom metadata to control rollout progression. Define rollout_pct as a custom key for each hostname. Set its value to an integer from 0 to 100. The expression selects approximately that percentage of requests:

hash_in_range(0, 100, cf.random_seed) < coalesce(lookup_json_integer(cf.hostname.metadata, "rollout_pct"), 0)

If rollout_pct is missing, coalesce() supplies 0. The rule then matches no requests.

For details, refer to the hash_in_range() function reference.

Compare dynamic values in Rules expressions

Cloudflare Rules expressions now support dynamic values on both sides of equality and ordering comparisons. You can compare request fields or function results with one another.

For example, compare the current request path with its original value:

http.request.uri.path ne raw.http.request.uri.path

For supported operators and examples, refer to Compare dynamic values.

Longer rule descriptions in logs

Cloudflare logs now include up to 128 bytes of a rule description, increased from 80 bytes. Longer descriptions provide more context when investigating matched rules and make it easier to identify the relevant rule without referring back to its configuration.

Descriptions longer than 128 bytes are truncated without splitting a UTF-8 character. This change does not affect the Rulesets API, which continues to accept rule descriptions of up to 4,096 bytes.

For more information, refer to Rule object structure and properties.

concat() now supports up to 32 arguments

The concat() function in Cloudflare Rules now accepts up to 32 arguments, increased from 16. This allows you to build richer dynamic values directly in Rules expressions and simplify configurations that combine request data.

A common use case is adding a request header that sends context to your origin. The following Rulesets API request adds a Request Header Transform Rule to an existing http_request_late_transform phase ruleset. Its 18-argument expression combines request and network information into one header value:

curl --request POST \
  "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/$RULESET_ID/rules" \
  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "ref": "add_request_context_header",
    "description": "Add request context for the origin",
    "expression": "true",
    "action": "rewrite",
    "action_parameters": {
      "headers": {
        "X-Request-Context": {
          "operation": "set",
          "expression": "concat(\"ip=\", to_string(ip.src), \";country=\", ip.src.country, \";host=\", http.host, \";method=\", http.request.method, \";path=\", http.request.uri.path, \";query=\", http.request.uri.query, \";ray-id=\", cf.ray_id, \";asn=\", to_string(ip.src.asnum), \";user-agent=\", http.user_agent)"
        }
      }
    }
  }'

For more information, refer to the concat() function reference and HTTP request header modification.

Validate Rulesets changes before deployment

Cloudflare Rules now validates ruleset changes before deployment, helping you catch invalid expressions, action parameters, permission issues, unavailable features, and quota limits without publishing the configuration.

The Cloudflare dashboard performs this validation automatically when you create or update rules from Security > Security rules or Rules > Overview.

Supported Rulesets API mutation endpoints now also accept the dry_run=true query parameter. A dry run performs the same authorization and server-side validation checks as the requested change, but does not persist or publish it. Successful operations that normally return a 200 response return result: null. Operations that normally return 204 continue to do so.

API example

Add dry_run=true to a Rulesets API request to validate it without creating the ruleset:

curl --request POST \
  "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets?dry_run=true" \
  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Custom firewall rules",
    "kind": "zone",
    "phase": "http_request_firewall_custom",
    "rules": [
      {
        "action": "block",
        "expression": "ip.src.country eq \"GB\"",
        "description": "Block requests from the United Kingdom",
        "enabled": true
      }
    ]
  }'

For more information, refer to Validate rule changes before deployment.

Oracle Cloud Infrastructure Object Storage support in Cloud Connector

Cloud Connector now supports public Oracle Cloud Infrastructure (OCI) Object Storage buckets. You can route matching requests to OCI without managing a separate origin-routing configuration.

OCI support uses the Amazon S3 Compatibility API. Both path-style and virtual-hosted endpoint formats are supported, including traditional oraclecloud.com and dedicated customer-oci.com path-style endpoints.

API example

Set provider to oci_storage and provide a supported OCI hostname. The following rule uses a virtual-hosted endpoint:

{
	"expression": "http.request.uri.path wildcard \"/assets/*\"",
	"provider": "oci_storage",
	"description": "Route assets to OCI Object Storage",
	"enabled": true,
	"parameters": {
		"host": "<BUCKET_NAME>.vhcompat.objectstorage.<REGION>.oci.customer-oci.com"
	}
}

For endpoint formats and bucket requirements, refer to Supported cloud providers in Cloud Connector.

Bot management fields and ASN support in Cache Rules

Bot management fields and ASN support in Cache Rules

Cache Rules now supports bot management fields and the ip.src.asnum field in expression filters. You can now build cache policies that differentiate between automated and human traffic, or segment caching behavior by autonomous system number (ASN).

This allows you to apply different caching strategies for verified bots, high-risk traffic, or specific network operators without affecting legitimate user requests. For example, you can set shorter cache TTLs for suspected bot traffic or bypass cache entirely for requests from specific ASNs.

New fields

The following fields are now available in Cache Rules expressions:

Field Type Description
cf.bot_management.score Number Bot score from 1 to 99, where a lower value indicates a higher likelihood that the request originates from a bot.
cf.bot_management.ja3_hash String JA3 fingerprint of the request, which helps identify the client making the connection.
cf.bot_management.ja4 String JA4 fingerprint of the request, which provides a more detailed client identification than JA3.
cf.bot_management.verified_bot Boolean Whether the request originates from a verified bot, such as a search engine crawler.
cf.bot_management.static_resource Boolean Whether the request is for a static resource and therefore exempt from bot detection.
cf.bot_management.js_detection.passed Boolean Whether the browser passed JavaScript detection when the feature is enabled.
cf.bot_management.detection_ids Array<Number> List of IDs that correspond to Bot Management heuristic detections made on the request.
cf.bot_management.tags Array<String> List of tags associated with the bot traffic, such as API, GOOGLE, or BING. Match a tag with an expression such as any(cf.bot_management.tags[*] eq "API").
cf.bot_management.signed_agent Boolean Whether the request originates from a known agent that identifies itself with Web Bot Auth.
cf.bot_management.corporate_proxy Boolean Whether the request originates from a known corporate proxy.
ip.src.asnum Number The autonomous system number (ASN) of the incoming request's IP address.

Example

Cache Rules expressions support combining these fields with other criteria. The following example sets a shorter cache TTL for API requests that originate from a high-risk bot or an unexpected ASN:

(http.request.uri.path contains "/api/" and cf.bot_management.score lt 30)
or
(http.request.uri.path contains "/api/" and not ip.src.asnum in {12345 67890})

To learn more, refer to the Cache Rules documentation and the Fields reference.

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 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 and the fields reference.

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 ↗︎ 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.

For more information, refer to Mutual TLS authentication, Request Header Transform Rules, and the fields reference.

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.

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.

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.

API example

{
  "action": "set_config",
  "action_parameters": {
    "request_body_buffering": "standard",
    "response_body_buffering": "none"
  }
}

For more information, refer to Configuration Rules.

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

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.

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.

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.

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.

More flexible fallback handling — Custom Errors now support fetching assets returned with 4xx or 5xx status codes

Custom Errors can now fetch and store assets and 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 documentation.

Match Workers subrequests by upstream zone — cf.worker.upstream_zone now supported in Transform Rules

You can now use the cf.worker.upstream_zone field in Transform Rules to control rule execution based on whether a request originates from Workers, including subrequests issued by Workers in other zones.

Match Workers subrequests by upstream zone in Transform Rules

What's new:

  • cf.worker.upstream_zone is now supported in Transform Rules expressions.
  • Skip or apply logic conditionally when handling Workers 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 documentation and Rules language fields reference.

Fine-tune image optimization — WebP now supported in Configuration Rules

You can now enable Polish with the webp format directly in 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 is now a supported value 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 and Configuration Rules documentation.

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 to route traffic to Snippets and 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 and WAF Attack Score, unlocking smarter edge logic for everything from request filtering and mitigation to tarpitting and logging.

What’s new:

  • Custom lists matching – Snippets and Cloud Connector now support user-created IP, AS, and Hostname lists via dashboard or Lists API. Great for shared logic across zones.
  • Bot Score and WAF 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

These enhancements unlock new possibilities for building smarter traffic workflows with minimal code and maximum efficiency.

Learn more in the Snippets and Cloud Connector documentation.

Custom Errors are now Generally Available

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 and override Error Pages for 500 and 1000 class errors, as well as errors originating from your origin or other Cloudflare products. You can also configure Response Header Transform Rules to add, change, or remove HTTP headers from responses returned by Custom Error Rules.

Learn more in the Custom Errors documentation.

Cloudflare Snippets are now Generally Available

Cloudflare Snippets are now GA

Cloudflare 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 to see which Snippets were triggered on a request — helping you understand traffic flow and debug more effectively.

    Snippets shown in Cloudflare Trace results

Learn more in the launch blog post ↗︎.

Increased Cloudflare Rules limits

We have upgraded and streamlined Cloudflare Rules limits across all plans, simplifying rule management and improving scalability for everyone.

New limits by product:

  • 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
    • Free: 5 → 10 connectors
    • Enterprise: 125 → 300 connectors
  • Custom Errors
    • Pro: 5 → 25 error assets and rules
    • Business: 20 → 50 error assets and rules
    • Enterprise: 50 → 300 error assets and 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, Configuration Rules, Compression Rules, Origin Rules, Single Redirects, and Transform Rules
    • Enterprise: 125 → 300 rules