---
title: Firewall rules upgrade · Cloudflare Web Application Firewall (WAF) docs
description: "Cloudflare upgraded existing firewall rules into custom rules.
  With custom rules, you get the same level of protection and a few additional
  features. Custom rules are available in the Cloudflare dashboard in the
  following location:"
lastUpdated: 2025-10-17T11:29:44.000Z
chatbotDeprioritize: false
source_url:
  html: https://developers.cloudflare.com/waf/reference/legacy/firewall-rules-upgrade/
  md: https://developers.cloudflare.com/waf/reference/legacy/firewall-rules-upgrade/index.md
---

Cloudflare upgraded existing [firewall rules](https://developers.cloudflare.com/firewall/) into [custom rules](https://developers.cloudflare.com/waf/custom-rules/). With custom rules, you get the same level of protection and a few additional features. Custom rules are available in the Cloudflare dashboard in the following location:

* Old dashboard: **Security** > **WAF** > **Custom rules**.
* New security dashboard: **Security** > **Security rules**.

Deprecation notice

**Cloudflare Firewall Rules is now deprecated.** The Firewall Rules API and Filters API, as well as the `cloudflare_firewall_rule` and `cloudflare_filter` Terraform resources, are no longer supported since 2025-06-15. If you have any automation based on these APIs and resources, you must migrate to the new APIs and resources to avoid any issues.

If you have not upgraded to WAF custom rules yet, you may have some invalid configuration that prevents the upgrade from happening. In this case, contact your account team to get help with the upgrade to WAF custom rules.

## Main differences

The main differences between firewall rules and WAF custom rules are the following:

* [Improved response for Block action](#improved-response-for-block-action)
* [Different error page for blocked requests](#different-error-page-for-blocked-requests)
* [New Skip action replacing both Allow and Bypass actions](#new-skip-action-replacing-both-allow-and-bypass-actions)
* [Custom rules are evaluated in order](#custom-rules-are-evaluated-in-order)
* [Logs and events](#logs-and-events)
* [New API and Terraform resources](#new-api-and-terraform-resources)

### Improved response for Block action

In WAF custom rules you can [customize the response of the *Block* action](https://developers.cloudflare.com/waf/custom-rules/create-dashboard/#configure-a-custom-response-for-blocked-requests).

The default block response is a Cloudflare standard HTML page. If you need to send a custom response for *Block* actions, configure the custom rule to return a fixed response with a custom response code (403, by default) and a custom body (HTML, JSON, XML, or plain text).

Note

Custom block response configurations are not returned by the Firewall Rules API. You must use the [Rulesets API](https://developers.cloudflare.com/waf/custom-rules/create-api/#example-b) to manage this new feature.

### Different error page for blocked requests

Requests blocked by a firewall rule with a *Block* action would get a Cloudflare [1020 error code](https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/error-1020/) response. Cloudflare users could customize this error page for a zone in **Error Pages** > **1000 class errors**.

Requests blocked by a WAF custom rule will get a different response: the WAF block response. To customize the default block response, you can either:

* Define a custom WAF block response for your entire zone in [**Error Pages**](https://dash.cloudflare.com/?to=/:account/:zone/error-pages) > **WAF block**. This error page will always have an HTML content type.
* [Define a custom response](https://developers.cloudflare.com/waf/custom-rules/create-dashboard/#configure-a-custom-response-for-blocked-requests) for requests blocked by a specific WAF custom rule. This custom response supports other content types besides HTML.

If you have customized your 1XXX error page in Error Pages for requests blocked by firewall rules, you will need to create a new response page for blocked requests using one of the above methods.

For more information on Error Pages, refer to [Custom Errors](https://developers.cloudflare.com/rules/custom-errors/).

### New Skip action replacing both Allow and Bypass actions

Firewall Rules supported the *Allow* and *Bypass* actions, often used together. These actions were commonly used for handling known legitimate requests — for example, requests coming from trusted IP addresses.

When a request triggered *Allow*, all remaining firewall rules were not evaluated, effectively allowing the request to continue to the next security product. The *Bypass* action was designed to specify which security products (such as WAF managed rules, rate limiting rules, and User Agent Blocking) should not run on the request triggering the action.

With Firewall Rules, if you wanted to stop running all security products for a given request, you would create two rules:

* One rule with *Bypass* action (selecting all security products).
* One rule with *Allow* action (to stop executing other firewall rules).

The requirement of having two rules to address this common scenario no longer applies to WAF custom rules. You should now [use the *Skip* action](https://developers.cloudflare.com/waf/custom-rules/skip/), which combines the *Allow* and *Bypass* actions. The *Skip* action fully replaces the *Allow* and *Bypass* actions, which are not supported in WAF custom rules.

With the *Skip* action you can do the following:

* Stop running all the remaining custom rules (equivalent to the *Allow* action)
* Avoid running other security products (equivalent to the *Bypass* action)
* A combination of the above.

You can also select whether you want to log events matching the custom rule with the *Skip* action or not. This is especially useful when creating a positive security model to avoid logging large amounts of legitimate traffic.

Note

The Firewall Rules API does not support the *Skip* action. When you create a custom rule with *Skip* action, it is translated to *Allow* and *Bypass* in the Firewall Rules API. You must use the [Rulesets API](https://developers.cloudflare.com/waf/custom-rules/skip/api-examples/) to fully use the new *Skip* action functionality.

### Custom rules are evaluated in order

Firewall rules actions had a specific [order of precedence](https://developers.cloudflare.com/firewall/cf-firewall-rules/actions/) when using [priority ordering](https://developers.cloudflare.com/firewall/cf-firewall-rules/order-priority/#managing-rule-evaluation-by-priority-order). In contrast, custom rules actions do not have such an order. Custom rules are always evaluated in order, and some actions like *Block* will stop the evaluation of other rules.

For example, if you were using priority ordering and had the following firewall rules with the same priority both matching an incoming request:

* Firewall rule #1 — Priority: 2 / Action: *Block*
* Firewall rule #2 — Priority: 2 / Action: *Allow*

The request would be allowed, since the *Allow* action in Firewall Rules would have precedence over the *Block* action.

In contrast, if you create two custom rules where both rules match an incoming request:

* Custom rule #1 — Action: *Block*
* Custom rule #2 — Action: *Skip* (configured to skip all remaining custom rules)

The request would be blocked, since custom rules are evaluated in order and the *Block* action will stop the evaluation of other rules.

Note

For the custom rules converted from your existing firewall rules, Cloudflare will preserve your current order of execution.

### Logs and events

Events logged by custom rules are shown in [Security Events](https://developers.cloudflare.com/waf/analytics/security-events/) with `Custom Rules` as their source.

You may still find events generated by Firewall Rules in the Security Events page when you select a time frame including the days when the transition to custom rules occurred. Similarly, you may still find events with both *Skip* and *Allow* actions in the same view during the transition period.

### New API and Terraform resources

The preferred API for managing WAF custom rules is the [Rulesets API](https://developers.cloudflare.com/waf/custom-rules/create-api/). The Rulesets API is used on all recent Cloudflare security products to provide a uniform user experience when interacting with our API. For more information on migrating to the Rulesets API, refer to [Relevant changes for API users](#relevant-changes-for-api-users).

The Firewall Rules API and Filters API are no longer supported since 2025-06-15. There is now a single list of rules for both firewall rules and WAF custom rules, and this list contains WAF custom rules. Thanks to an internal conversion process, the Firewall Rules API and Filters API return firewall rules/filters converted from these WAF custom rules until the APIs sunset date.

If you are using Terraform, you must update your configuration to use [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resources with the `http_request_firewall_custom` phase to manage custom rules. For more information on updating your Terraform configuration, refer to [Relevant changes for Terraform users](#relevant-changes-for-terraform-users).

## Relevant changes for dashboard users

**The Firewall Rules tab in the Cloudflare dashboard is now deprecated**. Firewall rules are displayed as [custom rules](https://developers.cloudflare.com/waf/custom-rules/) in the Cloudflare dashboard.

For users that have access to both products, the **Firewall rules** tab is only available in the old dashboard in **Security** > **WAF**.

## Relevant changes for API users

**The [Firewall Rules API](https://developers.cloudflare.com/firewall/api/cf-firewall-rules/) and the associated [Cloudflare Filters API](https://developers.cloudflare.com/firewall/api/cf-filters/) are now deprecated.** These APIs are no longer supported since 2025-06-15. You must manually update any automation based on the Firewall Rules API or Cloudflare Filters API to the [Rulesets API](https://developers.cloudflare.com/waf/custom-rules/create-api/) to prevent any issues. Rule IDs are different between firewall rules and custom rules, which may affect automated processes dealing with specific rule IDs.

Before the APIs sunset date, Cloudflare will internally convert your [Firewall Rules API](https://developers.cloudflare.com/firewall/api/cf-firewall-rules/) and [Filters API](https://developers.cloudflare.com/firewall/api/cf-filters/) calls into the corresponding [Rulesets API](https://developers.cloudflare.com/waf/custom-rules/create-api/) calls. The converted API calls between the Firewall Rules API/Filters API and the Rulesets API appear in audit logs as generated by Cloudflare and not by the actual user making the requests. There will be a single list of rules for both firewall rules and WAF custom rules.

Some new features of WAF custom rules, like custom responses for blocked requests and the *Skip* action, are not supported in the Firewall Rules API. To take advantage of these features, Cloudflare recommends that you use the custom rules page in the Cloudflare dashboard or the Rulesets API.

Refer to the WAF documentation for [examples of managing WAF custom rules using the Rulesets API](https://developers.cloudflare.com/waf/custom-rules/create-api/).

## Relevant changes for Terraform users

**The following Terraform resources from the Cloudflare provider are now deprecated:**

* [`cloudflare_firewall_rule`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/firewall_rule)
* [`cloudflare_filter`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/filter)

These resources are no longer supported since 2025-06-15. If you are using these resources to manage your Firewall Rules configuration, you must manually update any Terraform configuration to [`cloudflare_ruleset`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/ruleset) resources to prevent any issues.

There will be a single list of rules for both firewall rules and WAF custom rules.

Some new features of WAF custom rules are not supported in the deprecated Terraform resources. To take advantage of these features, Cloudflare recommends that you use the `cloudflare_ruleset` resource.

Refer to the documentation about Terraform for [examples of configuring WAF custom rules using Terraform](https://developers.cloudflare.com/terraform/additional-configurations/waf-custom-rules/).

### Replace your configuration using `cf-terraforming`

You can use the [`cf-terraforming`](https://github.com/cloudflare/cf-terraforming) tool to generate the Terraform configuration for your current WAF custom rules (converted by Cloudflare from your firewall rules). Then, import the new resources to Terraform state.

The recommended steps for replacing your firewall rules (and filters) configuration in Terraform with a new ruleset configuration are the following.

1. Run the following command to generate all ruleset configurations for a zone:

   ```sh
   cf-terraforming generate --zone <ZONE_ID> --resource-type "cloudflare_ruleset"
   ```

   ```txt
   resource "cloudflare_ruleset" "terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31" {
     kind    = "zone"
     name    = "default"
     phase   = "http_request_firewall_custom"
     zone_id = "<ZONE_ID>"
     rules {
       [...]
     }
     [...]
   }
   [...]
   ```

2. The previous command may return additional ruleset configurations for other Cloudflare products also based on the [Ruleset Engine](https://developers.cloudflare.com/ruleset-engine/). Since you are migrating firewall rules to custom rules, keep only the Terraform resource for the `http_request_firewall_custom` phase and save it to a `.tf` configuration file. You will need the full resource name in the next step.

3. Import the `cloudflare_ruleset` resource you previously identified into Terraform state using the `terraform import` command. For example:

   ```sh
   terraform import cloudflare_ruleset.terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31 zone/<ZONE_ID>/3c0b456bc2aa443089c5f40f45f51b31
   ```

   ```txt
   cloudflare_ruleset.terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31: Importing from ID "zone/<ZONE_ID>/3c0b456bc2aa443089c5f40f45f51b31"...
   cloudflare_ruleset.terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31: Import prepared!
     Prepared cloudflare_ruleset for import
   cloudflare_ruleset.terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31: Refreshing state... [id=3c0b456bc2aa443089c5f40f45f51b31]


   Import successful!


   The resources that were imported are shown above. These resources are now in
   your Terraform state and will henceforth be managed by Terraform.
   ```

4. Run `terraform plan` to validate that Terraform now checks the state of the new `cloudflare_ruleset` resource, in addition to other existing resources already managed by Terraform. For example:

   ```sh
   terraform plan
   ```

   ```txt
   cloudflare_ruleset.terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31: Refreshing state... [id=3c0b456bc2aa443089c5f40f45f51b31]
   [...]
   cloudflare_filter.my_filter: Refreshing state... [id=14a2524fd75c419f8d273116815b6349]
   cloudflare_firewall_rule.my_firewall_rule: Refreshing state... [id=0580eb5d92e344ddb2374979f74c3ddf]
   [...]
   ```

5. Remove any state related to firewall rules and filters from your Terraform state:

   Warning

   You must remove firewall rules and filters from Terraform state before deleting their configuration from `.tf` configuration files to prevent issues.

   1. Run the following command to find all resources related to firewall rules and filters:

      ```sh
      terraform state list | grep -E '^cloudflare_(filter|firewall_rule)\.'
      ```

      ```txt
      cloudflare_filter.my_filter
      cloudflare_firewall_rule.my_firewall_rule
      ```

   2. Run the `terraform state rm ...` command in dry-run mode to understand the impact of removing those resources without performing any changes:

      ```sh
      terraform state rm -dry-run cloudflare_filter.my_filter cloudflare_firewall_rule.my_firewall_rule
      ```

      ```txt
      Would remove cloudflare_filter.my_filter
      Would remove cloudflare_firewall_rule.my_firewall_rule
      ```

   3. If the impact looks correct, run the same command without the `-dry-run` parameter to actually remove the resources from Terraform state:

      ```sh
      terraform state rm cloudflare_filter.my_filter cloudflare_firewall_rule.my_firewall_rule
      ```

      ```txt
      Removed cloudflare_filter.my_filter
      Removed cloudflare_firewall_rule.my_firewall_rule
      Successfully removed 2 resource instance(s).
      ```

6. After removing firewall rules and filters resources from Terraform state, delete `cloudflare_filter` and `cloudflare_firewall_rule` resources from `.tf` configuration files.

7. Run `terraform plan` to verify that the resources you deleted from configuration files no longer appear. You should not have any pending changes.

   ```sh
   terraform plan
   ```

   ```txt
   cloudflare_ruleset.terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31: Refreshing state... [id=3c0b456bc2aa443089c5f40f45f51b31]
   [...]


   No changes. Your infrastructure matches the configuration.


   Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.
   ```

For details on importing Cloudflare resources to Terraform and using the `cf-terraforming` tool, refer to the following resources:

* [Import Cloudflare resources](https://developers.cloudflare.com/terraform/advanced-topics/import-cloudflare-resources/)
* [`cf-terraforming` GitHub repository](https://github.com/cloudflare/cf-terraforming)

## Final remarks

Any unpaused firewall rules with paused [filters](https://developers.cloudflare.com/firewall/api/cf-filters/what-is-a-filter/) will become enabled when converted to custom rules.
