> For the complete documentation index, see [llms.txt](https://docs.safetycli.com/safety-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.safetycli.com/safety-docs/firewall/using-firewall/understanding-firewall-messages.md).

# Understanding Firewall Messages

What Safety Firewall prints when you install packages: successful checks, blocked installs, failed installs, and warnings, and how to resolve each one.

Every install that runs through Safety Firewall ends with a short message telling you what was checked and what happened. This page lists each message you can see, what it means, and what to do about it.

| You see                                                           | It means                                           | Details                                                                           |
| ----------------------------------------------------------------- | -------------------------------------------------- | --------------------------------------------------------------------------------- |
| `✓ Safety Firewall checked N packages`                            | The install succeeded                              | [Successful Installs](#successful-installs)                                       |
| `× Safety Firewall blocked this install`                          | Your firewall policy blocked it                    | [Blocked Installs](#blocked-installs)                                             |
| `× pip install failed`                                            | The install failed for a reason other than policy  | [Installs That Failed (Not Blocked)](#installs-that-failed-not-blocked)           |
| `⚠ Safety Firewall: X was already present, so it was not blocked` | A blocked version bypassed the firewall            | [Package was already present](#package-was-already-present-so-it-was-not-blocked) |
| `⚠ Safety could not generate a report`                            | Safety could not show a summary of what it checked | [Report unavailable](#report-unavailable)                                         |

## Anatomy of a Firewall Message

Each message starts with a status symbol:

* `✓` The install succeeded and every package was checked.
* `×` The install did not complete. It was either blocked by the firewall policy or failed for another reason.
* `⚠` A warning. The install completed with something you should fix, Safety could not show a summary, or a package failed to install for a reason other than policy.
* `ⓘ` An informational note, such as a requested version that does not exist upstream.

Below the header, a message typically contains these fields:

| Field       | Meaning                                                         | When it appears                                                                                                                                           |
| ----------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Package`   | The package and version the message is about, and its registry  | Every message that names a package. The [report unavailable](#report-unavailable) warning does not name one                                               |
| `Reason`    | Why the package was blocked, warned about, or failed to install | Every message except a clean success                                                                                                                      |
| `Policy`    | Which firewall policy made the decision                         | Every block, and the [already present](#package-was-already-present-so-it-was-not-blocked) warning. Absent when no policy decided the outcome             |
| `Resolve`   | The suggested fix                                               | Only when the firewall can name a fix                                                                                                                     |
| `Report`    | Who to contact if you believe the result is wrong               | Every message except a clean success, an [upstream registry failure](#upstream-registry-failure), and a [report unavailable](#report-unavailable) warning |
| `Report ID` | The unique id of this check. Include it when contacting support | Every report, unless Safety could not reach the [report service](#report-unavailable) before the install                                                  |

Messages print on standard output, with one exception: the [report unavailable](#report-unavailable) warning prints on standard error.

## Successful Installs

### Clean install

The normal case. Everything you asked for was checked and installed:

```
✓ Safety Firewall checked 12 packages
  Report ID : 9a1e4d6b-0000-4000-8000-0000000000ff
```

### Installed, but with known vulnerabilities

When installed packages have known vulnerabilities that your policy still allows, the install succeeds and the firewall lists what it found:

```
✓ Safety Firewall checked 12 packages (2 with vulnerabilities)

  ╭───────────────┬──────────╮
  │ Package       │ Severity │
  ├───────────────┼──────────┤
  │ flask@2.0.1   │ high     │
  │ urllib3@2.0.7 │ medium   │
  ╰───────────────┴──────────╯

  Report ID : 9a1e4d6b-0000-4000-8000-0000000000ff
```

### Nothing to check

If a command installs nothing (for example, every requirement is already satisfied), Safety prints nothing at all. pip's own `Requirement already satisfied` output is all you see.

The firewall still checks the packages that were already installed, so silence means it found nothing to report. If one of them breaks a policy, you get the [already present](#package-was-already-present-so-it-was-not-blocked) warning instead.

## Blocked Installs

When the firewall policy refuses a package, the requested version is withheld from the package index. pip fails to install it, and the firewall explains why.

### Why packages get blocked

A block message names one of these reasons:

* **Known-malicious**: the version is confirmed malware.
* **Cooldown**: the version was released too recently. The policy holds back versions younger than a set window, for example 30 days. A window can also be set in weeks or months, and the reason names it as given, as in `your firewall policy's 2-week cooldown`.
* **Known vulnerabilities**: the version has vulnerabilities the policy does not allow.
* **Deny list or allow list**: the package is on your firewall policy's deny list, or is not on its allow list.
* **Blocked by firewall policy**: the version is blocked, but the firewall cannot name the specific cause.

The `Reason` line says what is wrong with the package. The `Policy` line below it says which policy decided that, so the name is printed once, in its own field:

* Normally it is the policy's name, as in `Policy : engineering-default`. It may be an organization-wide policy or one scoped to a single project.
* `Policy : default` means the firewall received no policy name for this decision. Most examples on this page show it.

A reason that names something your policy was configured to do calls it "your firewall policy", as in `below your firewall policy's 30-day cooldown` or `on your firewall policy's deny list`. Cooldown windows, deny lists and allow lists are all empty until someone sets them, so reaching one of those reasons means it was set. The two reasons where no configured rule made the call, [blocked by policy](#blocked-installs) and a version the firewall could not evaluate, say "the firewall policy" instead. Either way, the `Policy` line says which policy.

See [Firewall Policy Management](/safety-docs/firewall/using-firewall/firewall-policy-management.md) to configure these rules.

### Blocked with a specific reason

When you pin a version and the firewall knows why it is blocked, the message names the exact reason.

A known-malicious version:

```
× Safety Firewall blocked this install
  Package   : lodestone@0.0.58 (pypi)
  Reason    : this version is known-malicious
  Policy    : default
  Report    : contact your administrator or email support@safetycli.com
  Report ID : 9a1e4d6b-0000-4000-8000-0000000000ff
```

A version still inside a cooldown window, blocked by a policy the firewall can name:

```
× Safety Firewall blocked this install
  Package   : boto3@1.36.2 (pypi)
  Reason    : released 2 days ago, below your firewall policy's 30-day cooldown
  Policy    : engineering-default
  Resolve   : install boto3==1.35.99
  Report    : contact your administrator or email support@safetycli.com
  Report ID : 9a1e4d6b-0000-4000-8000-0000000000ff
```

The `Resolve` line appears when the report names a version that passed every policy. A block with no such version, a known-malicious one for example, shows `Reason` and `Report` only.

### Blocked without a specific reason

Sometimes the firewall knows your pinned version is blocked but cannot name the exact cause. The `Package` line then shows the name only, and the `Resolve` line points to a version you can install:

```
× Safety Firewall blocked this install
  Package   : requests (pypi)
  Reason    : the version you requested is blocked
  Policy    : default
  Resolve   : install requests==2.32.5
  Report    : contact your administrator or email support@safetycli.com
  Report ID : 9a1e4d6b-0000-4000-8000-0000000000ff
```

### No installable version at all

If you request a version range and no version in it is allowed:

```
× Safety Firewall blocked this install
  Package   : requests (pypi)
  Reason    : no version in your requested range (>=2.28,<2.32) is allowed
  Policy    : default
  Resolve   : install requests==2.32.5
  Report    : contact your administrator or email support@safetycli.com
  Report ID : 9a1e4d6b-0000-4000-8000-0000000000ff
```

If every version of the package is withheld, no version is installable at all:

```
× Safety Firewall blocked this install
  Package   : pycrypto (pypi)
  Reason    : all 12 versions are withheld
  Policy    : default
  Resolve   : no version of pycrypto is installable
  Report    : contact your administrator or email support@safetycli.com
  Report ID : 9a1e4d6b-0000-4000-8000-0000000000ff
```

A package with exactly one upstream version reads `the only version is withheld` instead. When versions were withheld by more than one policy, the `Policy` line lists them all, as in `Policy : engineering-default, org-baseline`.

### Resolving a block

Some block messages include a `Resolve` line with a suggested fix. When present, it takes one of two forms:

* `install X==Y`: the newest version the firewall audited and allowed.
* `no version of X is installable`: there is nothing safe to install. Contact your administrator if you need this package.

If you believe a block is wrong, the `Report` line says who to contact. Include the `Report ID`.

## Installs That Failed (Not Blocked)

A `× pip install failed` line followed by a Safety note means the install failed for a reason other than your policy.

### Upstream registry failure

```
× pip install failed
⚠ Safety Firewall failed to install the package
  Package   : requests (pypi)
  Reason    : fetching from the repository failed
  Report ID : 9a1e4d6b-0000-4000-8000-0000000000ff
```

The upstream registry could not serve the package. This is usually transient; retry the install.

### Version not found

```
× pip install failed
ⓘ Safety Firewall did not block this install
  Package   : requests@9.9.9 (pypi)
  Reason    : the requested version was not found in the upstream registry
  Resolve   : install requests==2.32.5
  Report    : contact your administrator or email support@safetycli.com
  Report ID : 9a1e4d6b-0000-4000-8000-0000000000ff
```

The version you pinned does not exist in the upstream registry. Check the pin for typos or a yanked release. The `Resolve` line names a version that does exist, and only appears when the firewall received version data for the package.

## Warnings

### Package was already present, so it was not blocked

The firewall can only block packages it serves. If a bad version is already installed, or is served from a local cache without reaching the firewall, the firewall warns you instead:

```
⚠ Safety Firewall: lodestone was already present, so it was not blocked
  Package   : lodestone@0.0.58 (pypi)
  Reason    : this version is known-malicious
  Policy    : default
  Report    : contact your administrator or email support@safetycli.com
  Report ID : 9a1e4d6b-0000-4000-8000-0000000000ff
```

Remove a known-malicious package before trying another version. The command exits 0, matching pip's behavior for packages that are already present.

### Report unavailable

If the Safety report service cannot be reached, the firewall cannot show you a summary. It prints this warning on standard error instead.

The install ran and was policy-checked, but there is no summary to show:

```
⚠ Safety could not generate a report
  Reason    : installed and policy-checked (Safety report service could not be
              reached)
  Report ID : 9a1e4d6b-0000-4000-8000-0000000000ff
```

If the service was unreachable before the install started, Safety never got a check id, so the `Report ID` line is missing:

```
⚠ Safety could not generate a report
  Reason    : installed and policy-checked (Safety report service could not be
              reached)
```

## Getting Help

If you believe a block is wrong, or you need a policy changed, contact your Safety administrator or email <support@safetycli.com> with:

1. The full message.
2. The `Report ID`. It lets support look up exactly what was checked and why it was decided.

For installation and configuration problems, see [Troubleshooting](/safety-docs/firewall/using-firewall/troubleshooting.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.safetycli.com/safety-docs/firewall/using-firewall/understanding-firewall-messages.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
