# Rule sets

A rule set is the object that holds what [Web Application Firewall](/en/documentation/platform/firewall/#waf) (WAF) looks for: the threat families it scores a request against, and the sensitivity level that turns a score into a block. Azion Console lists these under **WAF Rules**; the Azion API and the Azion CLI call the same object a `waf`.

A rule set does not act on its own. It runs when a rule in [Rules Engine for Firewall](/en/documentation/platform/firewall/rules-engine/) carries the **Set WAF** behavior naming it, together with a mode of *Logging* or *Blocking*. The mode belongs to that rule and not to the rule set, so one rule set runs in *Logging* on one rule and in *Blocking* on another. For more information, refer to [Scoring and modes](/en/documentation/platform/firewall/waf/scoring-and-modes/).

This page lists the fields of a rule set, the eight threat families it scores, the five sensitivity levels and their thresholds, the 63 internal rules behind the families, and the API and CLI surfaces that manage it.

---

## Fields

A rule set carries seven fields, four of which a request sets and three of which the platform sets and returns. The table below also lists the six nested fields inside `engine_settings`, so it runs to thirteen rows.

| Field                                                 | Type                                                      | Required  | Default                               | Description                                                                                |
| ----------------------------------------------------- | --------------------------------------------------------- | --------- | ------------------------------------- | ------------------------------------------------------------------------------------------ |
| `id`                                                  | integer                                                   | Read-only | —                                     | The identifier every later call uses                                                       |
| `name`                                                | string, 1 to 250 characters                               | Yes       | —                                     | The rule set name, unique within the account. The Console renders it as the **Name** field |
| `active`                                              | boolean                                                   | No        | `true`                                | Whether the rule set is active. The Console renders it as the **Active** switch            |
| `product_version`                                     | string, 3 to 50 characters, nullable, matching `\d+\.\d+` | No        | `1.0`                                 | The product version of the rule set                                                        |
| `last_editor`                                         | string, up to 250 characters                              | Read-only | —                                     | The email of the account that last changed the rule set                                    |
| `last_modified`                                       | date-time                                                 | Read-only | —                                     | When the rule set last changed                                                             |
| `engine_settings`                                     | object                                                    | No        | —                                     | The scoring engine and what it scores. Its fields follow                                   |
| `engine_settings.engine_version`                      | string                                                    | No        | `2021-Q3`                             | The engine build. `2021-Q3` is the only accepted value                                     |
| `engine_settings.type`                                | string                                                    | No        | `score`                               | How the engine decides. `score` is the only accepted value                                 |
| `engine_settings.attributes.rulesets`                 | array of integers                                         | No        | `[1]`                                 | The managed rule set the engine runs. `[1]` is the only accepted value                     |
| `engine_settings.attributes.thresholds`               | array of objects, 1 to 8 entries                          | No        | All eight threat families at `medium` | One entry per threat family, each carrying the sensitivity to apply to it                  |
| `engine_settings.attributes.thresholds[].threat`      | string                                                    | Yes       | —                                     | One of the eight values listed in Threat families                                          |
| `engine_settings.attributes.thresholds[].sensitivity` | string                                                    | No        | `medium`                              | One of the five values listed in Sensitivity levels                                        |

**Three fields accept exactly one value each.** `rulesets` accepts `[1]`, `engine_version` accepts `2021-Q3`, and `engine_settings.type` accepts `score`. Any other value returns `400` with `10039 Invalid Choice`, so a request that carries a second ruleset ID or a later engine version is rejected rather than downgraded.

`thresholds` holds between 1 and 8 entries. A request that names fewer than eight families is accepted and stores exactly what it sent, and a request that names the same family twice returns `500` rather than a validation error. The Console form always writes all eight. A create that sends no `engine_settings` at all produces a complete rule set: ruleset `[1]`, engine `2021-Q3`, type `score`, and all eight families at `medium`.

---

## Threat families

WAF scores a request against eight threat families. Each family carries its own sensitivity, so a request blocked for one family passes for another. The Console renders the eight as the **Threat Type Configuration** table on a rule set's **Main Settings** tab.

| Threat family                | API value               | What it detects                                                                                                                              |
| ---------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| SQL Injection                | `sql_injection`         | Detects an attempt to insert a SQL query through the input data the client sends to the application                                          |
| Remote File Inclusions (RFI) | `remote_file_inclusion` | Detects an attempt to include a remote file, usually through a script on the web server                                                      |
| Directory Traversal          | `directory_traversal`   | Detects insufficient sanitizing of user-supplied file names, where characters meaning "traverse to the parent directory" reach the file APIs |
| Cross-Site Scripting (XSS)   | `cross_site_scripting`  | Detects the injection of client-side scripts into pages other visitors view                                                                  |
| File Upload                  | `file_upload`           | Detects an attempt to upload a file                                                                                                          |
| Evading Tricks               | `evading_tricks`        | Detects encoding tricks used to evade protection mechanisms                                                                                  |
| Unwanted Access              | `unwanted_access`       | Detects an attempt to reach vulnerable or administrative pages, and the use of security scanning bots and tools                              |
| Identified Attack            | `identified_attack`     | Detects known attacks against common vulnerabilities in applications and servers                                                             |

Every family defaults to `medium`. Unwanted Access and Identified Attack are scored like the other six, and a create that sends no `thresholds` array carries all eight.

---

## Sensitivity levels

A request carries one score per threat family that fired, and each score is compared with the threshold of its own family. The request is blocked when a score reaches that threshold.

The threshold falls as the sensitivity rises. A higher sensitivity therefore blocks more requests on less evidence, and a lower sensitivity lets more requests through: `highest` blocks at a score of 4, and `lowest` blocks at 40.

| Level   | API value | Blocks at a score of | What it means                                                                                        |
| ------- | --------- | -------------------- | ---------------------------------------------------------------------------------------------------- |
| Highest | `highest` | 4                    | The narrowest tolerance. A single indicator of the family is enough to block                         |
| High    | `high`    | 8                    | Blocks on slight evidence, well short of what Medium asks for                                        |
| Medium  | `medium`  | 16                   | The recommended level, and the default. Blocks when the request carries substantial evidence         |
| Low     | `low`     | 24                   | Blocks only on strong evidence, and lets borderline requests through                                 |
| Lowest  | `lowest`  | 40                   | The widest tolerance. Blocks only on the strongest evidence, and produces the fewest false positives |

One sensitivity applies to one threat family, and each family is set independently. In the Console the option carries the word Sensitivity: the default option reads *Sensitivity Medium*.

Lowest and Low protect the application less and block fewer legitimate requests. High and Highest do the opposite, and they raise the number of false positives when the traffic already observed in *Logging* mode has not covered the variety of requests the application receives.

---

## Internal rules

Each internal rule carries a numeric identifier, and a rule that fires contributes to the score of the threat family it belongs to. The identifier is what an exception names when it allows a pattern the rule would otherwise score. For more information, refer to [WAF Exceptions](/en/documentation/platform/firewall/waf/custom-allowed-rules/).

| Rule ID | What it detects                                                                                                        |
| ------- | ---------------------------------------------------------------------------------------------------------------------- |
| `0`     | All rules. It carries no detection of its own and stands for every other rule in this table                            |
| `1`     | Protocol compliance: a weird request the engine cannot parse                                                           |
| `2`     | A request body too big to parse. The body is stored on disk and is not inspected                                       |
| `10`    | Protocol compliance: invalid HEX encoding, including null bytes                                                        |
| `11`    | Protocol compliance: a missing or unknown `Content-Type` header on a POST. Applies to the request body match zone only |
| `12`    | Protocol compliance: an invalid formatted URL                                                                          |
| `13`    | Protocol compliance: an invalid POST format                                                                            |
| `14`    | Protocol compliance: an invalid POST boundary                                                                          |
| `15`    | Protocol compliance: invalid JSON                                                                                      |
| `16`    | Protocol compliance: a POST with no body                                                                               |
| `17`    | Possible SQL Injection attack: validation with `libinjection_sql`                                                      |
| `18`    | Possible XSS attack: validation with `libinjection_xss`                                                                |
| `1000`  | Possible SQL Injection attack: SQL keywords in `Body`, `Path`, `Query String` or `Cookies`                             |
| `1001`  | Possible SQL Injection or XSS attack: double quote `"` in `Body`, `Path`, `Query String` or `Cookies`                  |
| `1002`  | Possible SQL Injection attack: possible hex encoding `0x` in `Body`, `Path`, `Query String` or `Cookies`               |
| `1003`  | Possible SQL Injection attack: MySQL comment `/*` in `Body`, `Path`, `Query String` or `Cookies`                       |
| `1004`  | Possible SQL Injection attack: MySQL comment `*/` in `Body`, `Path`, `Query String` or `Cookies`                       |
| `1005`  | Possible SQL Injection attack: MySQL keyword `\|` in `Body`, `Path`, `Query String` or `Cookies`                       |
| `1006`  | Possible SQL Injection attack: MySQL keyword `&&` in `Body`, `Path`, `Query String` or `Cookies`                       |
| `1007`  | Possible SQL Injection attack: MySQL comment `--` in `Body`, `Path`, `Query String` or `Cookies`                       |
| `1008`  | Possible SQL Injection or XSS attack: semicolon `;` in `Body`, `Path` or `Query String`                                |
| `1009`  | Possible SQL Injection attack: equal sign `=` in `Body` or `Query String`                                              |
| `1010`  | Possible SQL Injection or XSS attack: open parenthesis `(` in `Body`, `Path`, `Query String` or `Cookies`              |
| `1011`  | Possible SQL Injection or XSS attack: close parenthesis `)` in `Body`, `Path`, `Query String` or `Cookies`             |
| `1013`  | Possible SQL Injection or XSS attack: apostrophe `'` in `Body`, `Path`, `Query String` or `Cookies`                    |
| `1015`  | Possible SQL Injection attack: comma `,` in `Body`, `Path`, `Query String` or `Cookies`                                |
| `1016`  | Possible SQL Injection attack: MySQL comment `#` in `Body`, `Path`, `Query String` or `Cookies`                        |
| `1017`  | Possible SQL Injection attack: double at sign `@@` in `Body`, `Path`, `Query String` or `Cookies`                      |
| `1100`  | Possible RFI attack: scheme `http://` in `Body`, `Query String` or `Cookies`                                           |
| `1101`  | Possible RFI attack: scheme `https://` in `Body`, `Query String` or `Cookies`                                          |
| `1102`  | Possible RFI attack: scheme `ftp://` in `Body`, `Query String` or `Cookies`                                            |
| `1103`  | Possible RFI attack: scheme `php://` in `Body`, `Query String` or `Cookies`                                            |
| `1104`  | Possible RFI attack: scheme `sftp://` in `Body`, `Query String` or `Cookies`                                           |
| `1105`  | Possible RFI attack: scheme `zlib://` in `Body`, `Query String` or `Cookies`                                           |
| `1106`  | Possible RFI attack: scheme `data://` in `Body`, `Query String` or `Cookies`                                           |
| `1107`  | Possible RFI attack: scheme `glob://` in `Body`, `Query String` or `Cookies`                                           |
| `1108`  | Possible RFI attack: scheme `phar://` in `Body`, `Query String` or `Cookies`                                           |
| `1109`  | Possible RFI attack: scheme `file://` in `Body`, `Query String` or `Cookies`                                           |
| `1110`  | Possible RFI attack: scheme `gopher://` in `Body`, `Query String` or `Cookies`                                         |
| `1198`  | Possible RCE attack: validation with log4j (Log4Shell) in `Headers`                                                    |
| `1199`  | Possible RCE attack: validation with log4j (Log4Shell) in `Body`, `Path`, `Query String`, `Headers` or `Cookies`       |
| `1200`  | Possible Directory Traversal attack: double dot `..` in `Body`, `Path`, `Query String` or `Cookies`                    |
| `1202`  | Possible Directory Traversal attack: well-known probe `/etc/passwd` in `Body`, `Path`, `Query String` or `Cookies`     |
| `1203`  | Possible Directory Traversal attack: well-known Windows path `c:\` in `Body`, `Path`, `Query String` or `Cookies`      |
| `1204`  | Possible Directory Traversal attack: well-known probe `cmd.exe` in `Body`, `Path`, `Query String` or `Cookies`         |
| `1205`  | Possible Directory Traversal attack: backslash `\` in `Body`, `Path`, `Query String` or `Cookies`                      |
| `1206`  | Possible Directory Traversal attack: slash `/` in `Body`, `Query String` or `Cookies`                                  |
| `1207`  | Possible Directory Traversal attack: well-known path probe `/..;/` in `Body`, `Query String` or `Cookies`              |
| `1208`  | Possible Directory Traversal attack: well-known path probe `/.;/` in `Body`, `Query String` or `Cookies`               |
| `1209`  | Possible Directory Traversal attack: well-known path probe `/.%2e/` in `Body`, `Query String` or `Cookies`             |
| `1210`  | Possible Directory Traversal attack: well-known path probe `/%2e./` in `Body`, `Query String` or `Cookies`             |
| `1302`  | Possible XSS attack: HTML open tag `<` in `Body`, `Path`, `Query String` or `Cookies`                                  |
| `1303`  | Possible XSS attack: HTML close tag `>` in `Body`, `Path`, `Query String` or `Cookies`                                 |
| `1310`  | Possible XSS attack: open square bracket `[` in `Body`, `Path`, `Query String` or `Cookies`                            |
| `1311`  | Possible XSS attack: close square bracket `]` in `Body`, `Path`, `Query String` or `Cookies`                           |
| `1312`  | Possible XSS attack: tilde character `~` in `Body`, `Path`, `Query String` or `Cookies`                                |
| `1314`  | Possible XSS attack: back quote `` ` `` in `Body`, `Path`, `Query String` or `Cookies`                                 |
| `1315`  | Possible XSS attack: double encoding `%[2\|3]` in `Body`, `Path`, `Query String` or `Cookies`                          |
| `1400`  | Possible trick to evade protection: UTF7/8 encoding `&#` in `Body`, `Path`, `Query String` or `Cookies`                |
| `1401`  | Possible trick to evade protection: MS encoding `%U` in `Body`, `Path`, `Query String` or `Cookies`                    |
| `1402`  | Possible trick to evade protection: encoded chars `%20-%3F` in `Body`, `Query String` or `Cookies`                     |
| `1500`  | Possible File Upload attempt: `.ph`, `.asp` or `.ht` in a filename in a multipart POST carrying a file                 |
| `2001`  | Possible CVE-2022-22965 attack: Tomcat Pipeline Context tampering                                                      |

Rule `0` means all rules, and an exception created against it applies to every other rule in the table.

The Console's **Rule ID** dropdown offers 62 of these 63. Rule `1314` is absent from the list, and the API accepts it, so an exception for the back quote is created through the API or the CLI.

Some requests that fail rule `13` are blocked even when the rule set runs in *Logging* mode. For the request body size rule `2` measures, refer to [Firewall limits](/en/documentation/platform/firewall/limits/#waf).

---

## API

Every operation is authenticated and sits under `https://api.azion.com/v4/workspace/wafs`. A request carries a token from [Personal Tokens](/en/documentation/fundamentals/personal-tokens/) in the `Authorization` header under the `Token` scheme, and a request with a body also carries `Content-Type: application/json`.

| Operation                 | Method and path             |
| ------------------------- | --------------------------- |
| Create a rule set         | `POST /wafs`                |
| List rule sets            | `GET /wafs`                 |
| Retrieve a rule set       | `GET /wafs/{waf_id}`        |
| Replace a rule set        | `PUT /wafs/{waf_id}`        |
| Update part of a rule set | `PATCH /wafs/{waf_id}`      |
| Delete a rule set         | `DELETE /wafs/{waf_id}`     |
| Clone a rule set          | `POST /wafs/{waf_id}/clone` |

A create, a clone, and a partial update answer `202`, and the envelope carries a `state` of `pending` beside the object. A read answers `200` and carries `data` alone, with no `state` key.

### Create a rule set

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/wafs \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "my-waf-rule-set",
  "active": true,
  "product_version": "1.0",
  "engine_settings": {
    "engine_version": "2021-Q3",
    "type": "score",
    "attributes": {
      "rulesets": [1],
      "thresholds": [
        { "threat": "cross_site_scripting", "sensitivity": "medium" },
        { "threat": "directory_traversal", "sensitivity": "medium" },
        { "threat": "evading_tricks", "sensitivity": "medium" },
        { "threat": "file_upload", "sensitivity": "medium" },
        { "threat": "identified_attack", "sensitivity": "medium" },
        { "threat": "remote_file_inclusion", "sensitivity": "medium" },
        { "threat": "sql_injection", "sensitivity": "medium" },
        { "threat": "unwanted_access", "sensitivity": "medium" }
      ]
    }
  }
}'
```

The response carries `202`, and not `201`:

```json
{
  "state": "pending",
  "data": {
    "id": 12345,
    "active": true,
    "name": "my-waf-rule-set",
    "last_editor": "[ACCOUNT EMAIL]",
    "last_modified": "2026-01-01T12:00:00.000000Z",
    "product_version": "1.0",
    "engine_settings": {
      "engine_version": "2021-Q3",
      "type": "score",
      "attributes": {
        "rulesets": [1],
        "thresholds": [
          { "threat": "cross_site_scripting", "sensitivity": "medium" },
          { "threat": "directory_traversal", "sensitivity": "medium" },
          { "threat": "evading_tricks", "sensitivity": "medium" },
          { "threat": "file_upload", "sensitivity": "medium" },
          { "threat": "identified_attack", "sensitivity": "medium" },
          { "threat": "remote_file_inclusion", "sensitivity": "medium" },
          { "threat": "sql_injection", "sensitivity": "medium" },
          { "threat": "unwanted_access", "sensitivity": "medium" }
        ]
      }
    },
    "version_id": null,
    "version_state": null,
    "is_versioned": false,
    "version": null
  }
}
```

The `state` of `pending` says the rule set was accepted, and the `id` in `data` is the handle every later call uses. `last_editor` carries the email of the account that last changed the rule set, and the value above is a placeholder. The response also carries `version_id`, `version_state`, `is_versioned`, and `version`, which a create body does not set. The API returns the thresholds sorted by `threat`, whatever order the request sent them in.

### List rule sets

```bash
curl --request GET \
  --url https://api.azion.com/v4/workspace/wafs \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]'
```

The response carries `200` and the collection envelope below, with one rule set per entry under `results`, each in the shape the create response carries.

| Field         | What it carries                                              |
| ------------- | ------------------------------------------------------------ |
| `count`       | Rule sets the account holds                                  |
| `total_pages` | Pages the result divides into, at the current `page_size`    |
| `page`        | The page this response carries                               |
| `page_size`   | Rule sets per page. Defaults to 10                           |
| `next`        | The URL of the following page, or `null`                     |
| `previous`    | The URL of the preceding page, or `null`                     |
| `results`     | One rule set per entry, carrying the fields listed in Fields |

The endpoint accepts `fields`, `id`, `name`, `ordering`, `page`, `page_size`, and `search` as query parameters. `page_size` runs from 1 to 100 and defaults to 10. A value above 100 returns `400` with `10097 Invalid Page Size`.

### Retrieve, update, and delete a rule set

`GET /wafs/{waf_id}` answers `200` and returns the rule set under `data`.

`PUT /wafs/{waf_id}` replaces a rule set and takes the same body as a create. `PATCH /wafs/{waf_id}` takes only the fields sent and answers `202` with a `state` of `pending`. A `PATCH` that carries `engine_settings` replaces the whole `thresholds` array rather than merging it entry by entry, so a partial update sends every threat family the rule set is to keep.

`DELETE /wafs/{waf_id}` removes a rule set and answers `202` with a `state` of `pending`. While a rule's *Set WAF* behavior still applies the rule set, the delete is refused with `26007`.

### Clone a rule set

A clone is a deep copy of an existing rule set, including its exceptions.

```bash
curl --request POST \
  --url https://api.azion.com/v4/workspace/wafs/12347/clone \
  --header 'Accept: application/json' \
  --header 'Authorization: Token [TOKEN VALUE]' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "my-waf-rule-set-clone"
}'
```

The response carries `202`, a `state` of `pending`, and the new rule set: a new `id`, the `name` the request sent, and the threat families and sensitivities copied from the source. The API adds no suffix and derives no name of its own.

The body is required, and so is the `name` inside it. A clone sent with no body, or with an empty object, returns `400`:

```json
{
  "errors": [
    {
      "code": "10059",
      "title": "Required Field",
      "detail": "This field is required.",
      "status": "400",
      "source": {
        "pointer": "/data/name"
      }
    }
  ]
}
```

---

## CLI

The [Azion CLI](/en/documentation/devtools/cli/) manages rule sets under the `waf` noun. The flags below are the ones Azion CLI 4.23.0 carries, without the global flags every command takes.

| Command              | What it does                          |
| -------------------- | ------------------------------------- |
| `azion create waf`   | Creates a rule set                    |
| `azion list waf`     | Lists the rule sets the account holds |
| `azion describe waf` | Returns one rule set                  |
| `azion update waf`   | Changes a rule set                    |
| `azion delete waf`   | Removes a rule set                    |

`azion create waf` and `azion update waf` share their flags, except that `--product-version` belongs to the create and `--waf-id` to the update.

| Flag                | What it sets                                                                    |
| ------------------- | ------------------------------------------------------------------------------- |
| `--name`            | The rule set name                                                               |
| `--active`          | `true` or `false`                                                               |
| `--rulesets`        | The managed ruleset IDs, comma-separated. `1` is the only value the API accepts |
| `--thresholds`      | Comma-separated `threat=sensitivity` pairs, one per threat family               |
| `--engine-version`  | The engine build. `2021-Q3` is the only value the API accepts                   |
| `--type`            | The engine type. `score` is the only value the API accepts                      |
| `--product-version` | The product version. `azion create waf` only                                    |
| `--waf-id`          | The rule set to change. `azion update waf` only                                 |
| `--file`            | A JSON file carrying the body, or `-` to read the body from standard input      |

`azion list waf` takes `--details`, `--filter` to filter by name, `--order-by`, `--page` with a default of `1`, and `--page-size` with a default of `50`. `azion describe waf` and `azion delete waf` each take `--waf-id`.

A create that sets every threat family takes one `--thresholds` value:

```bash
azion create waf --name "my-waf-rule-set-cli" --active true --rulesets 1 \
  --thresholds "sql_injection=medium,cross_site_scripting=medium,directory_traversal=medium,evading_tricks=medium,file_upload=medium,identified_attack=medium,remote_file_inclusion=medium,unwanted_access=medium"
```

```text
Created WAF with ID 12346
```

A create that sets nothing but a name produces a complete rule set:

```bash
azion create waf --name "my-waf-rule-set-defaults"
```

```text
Created WAF with ID 12347
```

`azion describe waf --waf-id 12347 --format json` returns the stored rule set, with the keys sorted by the CLI:

```json
{"active": true,
 "engine_settings": {"attributes": {"rulesets": [1],
   "thresholds": [{"sensitivity": "medium", "threat": "cross_site_scripting"},
                  {"sensitivity": "medium", "threat": "directory_traversal"},
                  {"sensitivity": "medium", "threat": "evading_tricks"},
                  {"sensitivity": "medium", "threat": "file_upload"},
                  {"sensitivity": "medium", "threat": "identified_attack"},
                  {"sensitivity": "medium", "threat": "remote_file_inclusion"},
                  {"sensitivity": "medium", "threat": "sql_injection"},
                  {"sensitivity": "medium", "threat": "unwanted_access"}]},
  "engine_version": "2021-Q3", "type": "score"},
 "id": 12347, "is_versioned": false, "last_editor": "[ACCOUNT EMAIL]",
 "last_modified": "2026-01-01T12:00:30.00000Z", "name": "my-waf-rule-set-defaults",
 "product_version": "1.0", "version": null, "version_id": null, "version_state": null}
```

> **Note**
>
> The shipped help carries two examples that do not work. `azion create waf` shows `--rulesets "1,2,3"`, and `1` is the only ruleset the API accepts. `azion update waf` shows an `--in` flag, and the flag is `--file`.

---

## Errors

A rejected request returns an `errors` array. Each entry carries a `code`, a `title`, a `detail`, the `status`, and a `source` pointer naming the field the rejection is about:

```json
{
  "errors": [
    {
      "code": "10046",
      "title": "Max Length",
      "detail": "Ensure this field has no more than 250 characters.",
      "status": "400",
      "source": {
        "pointer": "/data/name"
      }
    }
  ]
}
```

| Code    | Title                  | Status | What causes it                                                                                                             | What to do                                                                                                                                                                                                              |
| ------- | ---------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `10004` | Not Found              | 404    | The platform's generic not-found. A `POST` to `/wafs/{waf_id}/exceptions` naming a `waf_id` that does not exist returns it | Check every segment of the path                                                                                                                                                                                         |
| `10009` | Unsupported Media Type | 415    | A write sent with a `Content-Type` other than `application/json`                                                           | Send `Content-Type: application/json`                                                                                                                                                                                   |
| `10018` | Blank Field            | 400    | A `name` that is an empty string                                                                                           | Send a `name` of 1 to 250 characters                                                                                                                                                                                    |
| `10039` | Invalid Choice         | 400    | A value outside an enum: `threat`, `sensitivity`, `rulesets`, `engine_settings.type`, or `engine_version`                  | Send one of the values the enum allows: the threat families are listed in Threat families, the sensitivity levels in Sensitivity levels, and the remaining three fields in Fields. The `source` pointer names the field |
| `10046` | Max Length             | 400    | A `name` longer than 250 characters                                                                                        | Shorten the name                                                                                                                                                                                                        |
| `10059` | Required Field         | 400    | A required field is absent, such as a clone sent with no `name`                                                            | Add the field the `source` pointer names                                                                                                                                                                                |
| `10067` | Internal Server Error  | 500    | The same `threat` twice in `thresholds`                                                                                    | Send one entry per threat family                                                                                                                                                                                        |
| `10097` | Invalid Page Size      | 400    | A `page_size` above 100 on a list request                                                                                  | Ask for 100 or fewer                                                                                                                                                                                                    |
| `26006` | Name Already In Use    | 400    | A `name` another rule set in the account already holds                                                                     | Choose another name                                                                                                                                                                                                     |
| `26007` | Cannot Delete WAF      | 400    | A `DELETE` on a rule set that a Rules Engine rule still applies through a `set_waf` behavior                               | Delete each rule the error names, or point its *Set WAF* at another rule set, then delete the rule set again                                                                                                            |

`10067` returns `500` for a client mistake. A repeated threat family is answered with the text `A server error occurred.`, which names neither the duplicate nor the field, so a reader who trusts the status code concludes the platform is down, and a retry returns the same `500`. Its `source` pointer reads `/data/attributes/thresholds`, one segment short of the pointer every other threshold error returns.

`26007` names each rule that still applies the rule set twice, as `<firewall-name> - <rule-name>`: once in the `detail`, `It was not possible to perform this operation. To delete this WAF, you must first remove its usage in the following rules engine: ['<firewall-name> - <rule-name>'].`, and once as an entry of `meta.ef_rules_using_waf`. Its `source` pointer reads `/data`.

---

## Related resources

- [Scoring and modes](/en/documentation/platform/firewall/waf/scoring-and-modes.md): The scoring model behind these thresholds, and the two modes a rule applies a rule set in.
- [Create and apply a WAF rule set](/en/documentation/guides/application-security/firewall-and-waf/create-waf-rule-set.md): The procedure that creates a rule set and applies it through Rules Engine for Firewall.
- [Data Stream](/en/documentation/platform/data-stream.md): The WAF event template that streams what a rule set scored to your own destination.
- [Real-Time Events](/en/documentation/platform/real-time-events.md): The raw request logs that show which rule fired and what it scored.
