How to Safely Disable and Delete Unused FortiGate Firewall Rules

Deleting firewall policies sounds straightforward — find the unused rules, remove them. In practice, engineers who skip a proper validation process routinely break application flows they didn’t know existed. This guide covers a repeatable disable-verify-delete workflow that gives you confidence before any rule is permanently removed.

Why Unused Rules Are Risky to Delete Immediately

A policy with zero hit count over the past 90 days is the strongest signal that it is safe to remove. But zero hit count alone is not conclusive. Some applications run quarterly batch jobs; others are activated only during DR tests or seasonal peaks. A rule that looks dead in normal operation may be critical at 2 AM on the last day of the financial quarter.

The flowchart below illustrates the safe workflow. The critical gate is a 30-day monitoring window after disabling — not deleting — the rule.


Safe FortiGate Policy Deletion Workflow

1. Identify Unused
Hit count = 0 for 90+ days

2. Check Dependencies
Objects used elsewhere?

Safe to
proceed?

YES

3a. Disable Rule
set status disable

NO

3b. Document & Skip
Add comment, review later

4. Monitor 30 Days
Check traffic logs daily

5. Delete Rule
config firewall policy / delete N

Legend

Fortinet Red

Review

Safe

Step 1 — Identify Unused Policies

Use hit count data as your starting list. From the CLI:

diagnose firewall iprope show 100004 0

Filter to policies with 0 packets. You can also use the APO Tool to generate a clean report of zero-hit policies across your entire table, including the last-matched timestamp where available.

Step 2 — Check for Object Dependencies

Before touching a rule, check whether its address objects, service objects, or schedule objects are referenced by other policies. Deleting the rule may not matter, but if you later clean up orphaned objects, you could break something.

config firewall addrgrp
    show | grep "ADDR-OBJECT-NAME"
end

In the GUI: right-click an address object and select “Where Used” to see all policy references.

Step 3a — Disable, Don’t Delete Yet

For each candidate policy, disable it instead of deleting:

config firewall policy
    edit 112
        set status disable
    next
end

Disabled rules remain in the policy table but process no traffic. They are visible in the GUI with a greyed-out row. This state is instantly reversible if you need to roll back.

Step 4 — Monitor for 30 Days

Watch the traffic logs for application errors, user complaints, or unexpected drops. In FortiAnalyzer or the local log viewer:

Log & Report > Forward Traffic — filter by policyid=112

If traffic arrives that matches the now-disabled rule, FortiGate will fall through to the next matching rule or hit the implicit deny. That miss will show up as a traffic log entry with action=deny, which is exactly the signal you need to detect a false-positive.

Step 5 — Delete After Validation

If no incidents occurred during the 30-day window, delete the policy permanently:

config firewall policy
    delete 112
end

Immediately backup the configuration after deletions:

execute backup config ftp <ftp-server> <filename>

Rollback Plan

Always have a rollback plan before bulk deletions. The safest approach: export the full running config before your change window. If something breaks, restoring the config via System > Config > Restore returns to the exact pre-change state within minutes.

Batch Deletion with a Script

For large cleanups (50+ rules), scripting the disablement phase reduces errors. Prepare a text file with one policy ID per line, then iterate:

for policy_id in $(cat unused_policies.txt); do
  echo "config firewall policy"
  echo "  edit $policy_id"
  echo "    set status disable"
  echo "  next"
  echo "end"
done | ssh admin@fortigate

Run this during a maintenance window, monitor for 30 days, then run the same loop with delete $policy_id replacing the disable block.

Documenting What You Deleted and Why

After every deletion cycle, update your change management records with three data points for each removed policy: the policy ID and name that was removed, the last known hit count and date, and the change ticket reference that authorised the deletion. This documentation serves two purposes: it provides an audit trail for compliance reviewers, and it gives you a reference if someone later asks “why was access to this system removed?”

Store the pre-deletion configuration backup with the same reference number. If a question arises six months later, you can pull the backup, inspect the rule, and demonstrate both the evidence that led to the decision and the authorisation that approved it.

For more context on identifying which policies qualify for this workflow, see our previous post on FortiGate hit count zero policies.

How to Safely Disable and Delete Unused FortiGate Firewall Rules Without Surprises

The safest deletion workflow uses a minimum 30-day disabled observation window for normal business traffic and 90 days for backup, disaster recovery, or quarterly finance systems. During that window, monitor FortiAnalyzer logs, service desk tickets, and application owner feedback. If a disabled policy causes impact, re-enable it immediately and document why the original zero-hit signal was misleading.

Related FortiGate Cleanup Guide

Related baseline: FortiGate zero-hit policy cleanup guide.

When the same checks need to be repeated across multiple firewalls, APO Tool helps reduce manual review time while keeping the final change decision with the network security team.

Frequently Asked Questions

Q: Should I delete a zero-hit FortiGate policy immediately?

A: No. Disable it first, monitor for 30 to 90 days, and delete only after business owners confirm there is no impact.

Q: What is the safest rollback step?

A: Keep the original policy ID, export the rule before changing it, and re-enable the disabled policy if traffic breaks.

Leave a comment