Safeguard
Security Guides•

Compensating control or not reachable: which label is honest?

A vulnerable component can be unused, or used and shielded by another control. They need different labels, evidence and reviews. How to choose.

Safeguard Security Team
4 min read

Use "not reachable" when the vulnerable code cannot be executed in your build. Use "compensating control" when it can be executed but something else stands in the way of exploitation. The first is a fact about code. The second depends on a control that can fail, so it needs its own owner, test and review date.

Two situations that look alike on a ticket

A finding is closed with the note "not a risk". Is that because nothing calls the function, or because a gateway filters the malicious input? From the ticket you cannot tell, and an auditor will ask.

The distinction matters because the evidence differs and the failure modes differ.

QuestionNot reachableCompensating control
What is the claim?No call path to the vulnerable code in this buildCode can run, but exploitation is blocked or limited
What proves it?Analysis result, build and commitControl configuration plus a test that shows it works
What breaks it?A code change that adds a callA configuration change or a bypass
Who owns it?Application teamWhoever owns the control
Review triggerRelease or dependency changeControl change or new bypass technique

What the standards vocabulary says

The OpenVEX specification lists a set of justification labels for a not affected claim. One is vulnerable code not in execute path, used when the product includes the vulnerable component but does not call it. Another is inline mitigations already exist, described as built in protections that cannot be subverted by the attacker and cannot be configured or disabled by the user.

The specification adds a caution on that last label: it could be difficult to prove conclusively, and mitigation bypasses are common. That caution is the reason to treat an external control differently from an absent call path. A web application firewall in front of the service is not a built in protection of the product.

How to record each

For not reachable, keep the analysis date, tool, scope and the absence of a path. Re-run it on each release.

For a compensating control, record:

  1. The control and where it runs.
  2. The specific attack it is expected to stop.
  3. A test that demonstrates it stopping a safe sample.
  4. The owner and the review date.
  5. What happens if the control is removed.

The last point is the one teams skip. If the control is turned off during a migration, the finding is live again.

Do not stack labels to look safer

Some records say "not reachable, and also mitigated by the firewall". If the code is truly not reachable, the second claim adds noise. If you are unsure about reachability, say so and rely on the control openly. A clear single reason beats two vague ones.

Choosing quickly

Ask: if the control vanished tomorrow, would the finding still be harmless? If yes, the reason is reachability. If no, the reason is the control, and you should label it that way.

Try it yourself

Click through it at your own pace, or open it full screen. Look at which facts change the verdict.

Quick check

Can a compensating control justify a VEX not affected statement?

Only if the mitigation is built into the product and cannot be turned off by the user. An external control is better described in an action or impact statement.

How often should a compensating control be reviewed?

On any change to the control, and on a fixed schedule your policy names.

Safeguard runs reachability analysis and keeps decision records with dates and owners. You can try the free scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.