By Manny Fernandez

September 25, 2026

diagnose firewall iprope: Reading the FortiGate Policy Engine From the Kernel Up

What the kernel actually enforces, how to read it, and the troubleshooting workflows that make it worth knowing

Executive Summary

Every FortiGate admin knows show firewall policy. Far fewer know what happens after you type end. FortiOS compiles each policy into kernel rule entries, called iprope entries, grouped by function (forward traffic, local-in, VIP, implicit, shaping, and more). The packet path is evaluated against those compiled entries, not against your CLI text.

diagnose firewall iprope is the window into that compiled table. It shows what the kernel is really enforcing (including resolved FQDN and dynamic address ranges), per-policy packet and hit counters, a policy match simulator, and a live “top” view of your busiest rules. If you have ever asked “why is this traffic hitting that policy?” or “is this rule even used?”, this is the command family you want.

Item Detail
Objective Understand every diagnose firewall iprope subcommand, decode its output, and apply it to real troubleshooting and policy hygiene workflows
Audience FortiGate administrators, SEs, and SOC/NOC engineers comfortable in the FortiOS CLI
Tested against FortiOS 7.0 through 7.6 CLI syntax (8.0 CLI reference lists the same subcommands). Output layout shifts slightly between builds.
Lab addressing 10.0.0.0/16 for internal LANs, 198.18.0.0/15 for public/transit

1. What iprope Actually Is

Think of config firewall policy as source code and iprope as the compiled binary. When a policy is saved, FortiOS translates it into a kernel entry: interface names become interface indexes, address objects become numeric IP ranges, services become protocol and port tuples, and security profile settings become flags. Those entries live in numbered policy groups, and the kernel walks the relevant group when a new session needs a verdict.

Three things follow from that:

  • The kernel view can differ from the config view. An FQDN that never resolved, an empty address group, or a dynamic address with no members compiles to something that will not match what you expect. iprope list shows you the truth.
  • Hidden policies exist. Implicit deny, local-in rules generated from interface allowaccess, VIP handling, and similar entries live in their own groups and are visible here even when the GUI hides them.
  • Counters live at the kernel. The Bytes, Hit Count, and Last Used columns in the GUI are read from these same counters.
VDOM scope: iprope tables are per VDOM. On a multi-VDOM unit, enter the VDOM first (config vdom then edit <vdom>) or you will be reading the wrong table. IPv6 has a parallel command tree: diagnose firewall iprope6 with the same subcommands.

2. Subcommand Map

Subcommand What it does Typical use
list [group] [id] Dumps compiled kernel entries for a group (or all groups) Verify what is actually enforced, check resolved objects
show <group> <id> [id...] Per-policy statistics: packets, bytes, offload counters, hit count, first/last hit Is this rule used? Is traffic offloaded?
clear <group> [id...] Resets statistics for one or more policies Clean before/after test
lookup <5-tuple> <intf> ... Simulates the policy match for a flow Which policy will this traffic hit?
state Engine allocation counters and the list of active groups Discover group IDs, health snapshot
top <group> <sort> ... Live ranked view of the busiest policies Find the rules carrying the load
appctrl ... Kernel-side application control list data Legacy app control troubleshooting

3. Policy Groups: The Numbers That Matter

Most iprope subcommands take a group ID. Group IDs are hexadecimal, and the leading zeros are optional, so 100004 and 00100004 are the same group. These are the ones you will use most:

Group Contents
00100004 Standard firewall policies (forward traffic). This is your config firewall policy table and the group you will use 90% of the time.
00100001 Local-in policies (traffic destined to the FortiGate itself)
00100000 VIP-related firewall policy entries
00100002 Static SNAT entries
0010000e Implicit policies as shown in the GUI
00100015 Traffic shaping policies
Do not memorize the whole list. Group numbering has shifted across major releases. Run diagnose firewall iprope state on your build; the total group number line and the hex IDs after it tell you exactly which groups exist. Then list each one you are curious about.

4. iprope list: The Compiled Policy Table

Syntax

diagnose firewall iprope list                  # every group (long!)
diagnose firewall iprope list 100004           # all forward policies
diagnose firewall iprope list 100004 12        # only policy ID 12

On a busy firewall the unfiltered output is thousands of lines. Scope it by group and ID, or pipe through FortiOS grep with context lines:

diagnose firewall iprope list 100004 | grep -A 15 "index=12 "

Sample output

Representative output for a LAN-to-internet policy with NAT and security profiles (exact lines vary by build):

FGT-EDGE (root) # diagnose firewall iprope list 100004 12

policy index=12 uuid_idx=731 action=accept
flag (8050108): redir nat master use_src pol_stats
flag2 (4000): resolve_sso
flag3 (a0): link-local best-route
schedule(always)
cos_fwd=255  cos_rev=255
group=00100004 av=00004e20 au=00000000 split=00000000
host=4 chk_client_info=0x0 app_list=0 ips_view=0
misc=0 dd_type=0 dd_mode=0
zone(1): 9 -> zone(1): 5
source(1): 10.0.10.0-10.0.10.255, uuid_idx=402,
dest(1): 0.0.0.0-255.255.255.255, uuid_idx=6,
service(1):
    [6:0x0:0/(0,65535)->(443,443)] helper:auto

Field reference

Field Meaning What to look for
index Policy ID from config firewall policy Matches edit <id>, not the GUI sequence number
uuid_idx Kernel index of the policy UUID Correlates with UUID-based logging
action accept or deny A deny you did not expect is a config problem, not a kernel one
flag / flag2 / flag3 Hex bitmask plus decoded names nat means SNAT is on; pol_stats means counters are collected; redir typically appears when traffic is handed to an inspection daemon. Compare against a known-good policy rather than memorizing bits.
schedule(...) Attached schedule A recurring or one-time schedule outside its window means the entry will not match
group Group this entry belongs to Confirms you are reading the right table
zone(n): A -> zone(n): B Ingress and egress interface indexes Map indexes to names with diagnose netlink interface list
source(n) / dest(n) Resolved IP ranges, count in parentheses The single most useful line. FQDN, geo, and dynamic objects show their resolved ranges here. A count of 0 or a missing range means the object resolved to nothing.
service(n) [proto:flags:src-ports->dst-ports] tuples Protocol 0 means any. (0,65535) source port is normal.

To translate the zone indexes into interface names:

diagnose netlink interface list | grep "index=9 "
diagnose netlink interface list | grep "index=5 "

5. iprope show: Per-Policy Statistics

Syntax

diagnose firewall iprope show 100004 12
diagnose firewall iprope show 100004 12 14 27 31     # several IDs at once
diagnose firewall iprope show 100001 3                # a local-in policy

There is a practical limit on how many IDs one command accepts (community reports put it around a dozen), so batch large audits.

Sample output

FGT-EDGE (root) # diagnose firewall iprope show 100004 12
idx=12 pkts/bytes=14709/18777329 asic_pkts/asic_bytes=8087/10413737
nturbo_pkts/nturbo_bytes=8087/10413737 flag=0x0
hit count:19 (4 7 0 1 1 3 3 0) first:2026-09-17 17:09:00
last:2026-09-23 17:23:40 established session count:0
first est:2026-09-17 17:11:20 last est:2026-09-23 17:23:40
Field Meaning
pkts/bytes Traffic counted against the policy. On NP-equipped hardware, the CPU-path counts are typically the smaller number.
asic_pkts/asic_bytes Traffic handled by the NP processor (hardware offload)
nturbo_pkts/nturbo_bytes Traffic accelerated through nTurbo (IPS/flow inspection fast path)
hit count Number of times the policy was matched for a new session
(4 7 0 1 ...) Seven-day rolling counter: the current day plus the previous seven days of hit counts, so you can see trend, not just a lifetime total
first / last First and most recent hit timestamps
established session count Sessions currently active on this policy
first est / last est First and most recent established session timestamps
Reading offload at a glance: if pkts barely moves while asic_pkts climbs, the policy is working and the NP is doing the heavy lifting. If asic_pkts stays at 0 on hardware that should offload, check whether a proxy-based profile, a session helper, or auto-asic-offload disable is keeping the traffic on the CPU.

6. iprope clear: Reset the Counters

diagnose firewall iprope clear 100004 12            # one policy
diagnose firewall iprope clear 100004 3 12 48 4     # several policies
diagnose firewall iprope clear 100004               # EVERY policy in the group

Clearing only zeros the statistics; the policy itself is untouched. It is also the same reset as right-clicking a policy in the GUI and choosing Clear Counters, so the GUI Hit Count and Last Used columns reset too.

Careful with the no-ID form. Running clear with a group and no policy ID wipes the counters for the whole group. If someone is relying on hit counts for an unused-rule audit, you just destroyed their data. These counters survive a reboot, so they are often the only long-term usage record on a box without FortiAnalyzer.

7. iprope lookup: The Policy Match Simulator

lookup answers “which policy would this flow hit?” without sending a packet. It is the CLI equivalent of the GUI Policy Lookup tool (renamed Policy Match in 7.4).

Syntax

diagnose firewall iprope lookup <src_ip> <src_port> <dst_ip> <dst_port> \
  <protocol> <src_interface> [<pol_type>] [<auth_type>] [<user/group>] \
  [<server>] [<user-db>] [<group-attr-type>]
Argument Notes
src_ip / src_port Client address and port. Port 0 is fine for most lookups.
dst_ip / dst_port Destination. For ICMP, this field takes type/code, for example 8/0 for echo request.
protocol Protocol number (6 TCP, 17 UDP, 1 ICMP). Many builds also accept tcp/udp; numbers are the safe choice.
src_interface The ingress interface name, exactly as FortiOS names it (port5, internal, a VLAN, a tunnel, ssl.root)
pol_type Newer builds: policy (firewall policy) or proxy (explicit proxy policy)
auth arguments Newer builds: auth type (ldap, saml, local, group), user or group name, server, user database, and group attribute type, for identity-based policies

The argument list grew across releases. Type the command through the interface name and press ? to see exactly what your build accepts.

Examples

# HTTPS from a LAN client to a public server
diagnose firewall iprope lookup 10.0.10.25 51514 198.18.40.10 443 6 port5
<src [10.0.10.25-51514] dst [198.18.40.10-443] proto 6 dev port5>
  matches policy id: 12

# DNS over UDP
diagnose firewall iprope lookup 10.0.10.25 0 198.18.53.53 53 17 port5
<src [10.0.10.25-0] dst [198.18.53.53-53] proto 17 dev port5> matches policy id: 14

# ICMP echo request (type/code in the dst_port field)
diagnose firewall iprope lookup 10.0.10.25 0 198.18.40.10 8/0 1 port5

# Explicitly test a firewall policy (not a proxy policy) on newer builds
diagnose firewall iprope lookup 10.0.10.25 0 198.18.40.10 443 6 port5 policy
**matches policy id: 0 means implicit deny.** Nothing in the table matched. Before you blame the policy, check the gotchas in section 11: a missing route, the wrong VRF, or an identity-based policy are the usual reasons a correct-looking rule is skipped.

Remember that lookup is a simulation. It is excellent for “what should happen”, but when a real flow misbehaves, confirm with a flow trace (section 10), which reports the policy the packet actually hit.

8. iprope state: Engine Snapshot and Group Discovery

diagnose firewall iprope state

The output includes allocation counters for the policy engine (iprope entries, shapers, users, nodes, policies) and a total group number line followed by the hex IDs of every active group. Two practical uses:

  • Group discovery. The IDs listed here are the valid arguments for list, show, and top on this build.
  • Health snapshot. Fortinet includes diagnose firewall iprope state in its own high-CPU and high-memory automation stitch examples, so it belongs in any diagnostic capture script you run through an automation stitch CLI action.

9. iprope top: Your Busiest Rules, Live

Newer builds (the 7.6 and 8.0 CLI references list it) add a top-style view of policy statistics within a group.

diagnose firewall iprope top <group> <sort_key> [delay_sec] [count] [iterations]
Argument Values
sort_key pkts, asic-pkts, hit-count, nturbo-pkts, tcp-ses, udp-ses, sctp-ses, all-ses, each also available with a -rate suffix (for example hit-count-rate)
delay_sec Refresh interval, default 5
count Number of policies to display, default 10
iterations Number of refreshes, default unlimited. Press Ctrl+C to exit an unlimited run.
# Top 10 forward policies by new-session rate, refresh every 5s, 3 cycles
diagnose firewall iprope top 100004 hit-count-rate 5 10 3

# Which rules are carrying the most CPU-path packets right now?
diagnose firewall iprope top 100004 pkts-rate 2 15

The -rate keys are the interesting ones during an incident: they show what is hot right now rather than what has accumulated since the last counter reset. A sudden spike in pkts-rate on a rule that should be offloaded is a strong hint about a CPU problem.

10. Practitioner Workflows

Workflow A: “Why is this traffic hitting the wrong policy?”

Goal: go from symptom to root cause in three commands.

# 1. What SHOULD happen?
diagnose firewall iprope lookup 10.0.10.25 0 198.18.40.10 443 6 port5

# 2. What does the kernel think that policy contains?
diagnose firewall iprope list 100004 12

# 3. What DOES happen to a real packet?
diagnose debug reset
diagnose debug flow filter addr 198.18.40.10
diagnose debug flow filter port 443
diagnose debug flow show function-name enable
diagnose debug flow trace start 20
diagnose debug enable
# ...generate traffic, then look for "Allowed by Policy-N"
# or "Denied by forward policy check"
diagnose debug disable
diagnose debug reset

If the lookup and the flow trace disagree, the difference is almost always routing (the trace shows the egress interface the route actually selected) or identity (the trace was for an unauthenticated user).

Workflow B: Unused and shadowed rule audit

Goal: find policies with zero or stale hits before a cleanup.

# Batch the IDs you want to review
diagnose firewall iprope show 100004 3 4 7 9 12 14 18 21 22 27

# Look for: hit count:0, or a 'last:' date months in the past,
# or a rolling counter of (0 0 0 0 0 0 0 0) over a busy week

A policy that never gets hits while a broader policy above it is busy is a shadowing candidate. Confirm with lookup using a flow that the lower policy was written for; if the answer is the upper policy ID, the lower one is shadowed.

Workflow C: Did that FQDN or dynamic address actually resolve?

diagnose firewall iprope list 100004 31 | grep -A 3 "dest("

# Cross-check the object itself
diagnose firewall fqdn list-ip
diagnose firewall dynamic list

If dest(0) appears, or the ranges do not include the IP you expect, the policy cannot match that destination no matter how correct the config looks. Fix DNS (for FQDN objects) or the connector (for dynamic objects) first.

Workflow D: Audit what can reach the FortiGate itself

diagnose firewall iprope list 100001

# Compare with the configured local-in policies
show firewall local-in-policy

Group 00100001 includes entries you never typed, derived from interface allowaccess and enabled services. It is a fast way to confirm that management exposure on a WAN interface is what you think it is.

Workflow E: Confirm a FortiManager install landed

show firewall policy 12
diagnose firewall iprope list 100004 12

If the config shows the new address object but the kernel source() or dest() ranges still reflect the old one, the install did not fully apply, or an object in the new policy failed to resolve.

Workflow F: Controlled before and after test

diagnose firewall iprope clear 100004 12
# ...generate a known test flow from 10.0.10.25...
diagnose firewall iprope show 100004 12

# See the sessions riding the policy right now
diagnose sys session filter clear
diagnose sys session filter policy 12
diagnose sys session list

11. Troubleshooting and Gotchas

Symptom Likely cause Fix
lookup returns policy 0 for traffic that clearly should match No route to the destination (egress interface cannot be resolved), wrong VRF, or the policy requires user/group identity Check get router info routing-table details <dst>; add the auth arguments on newer builds; confirm with debug flow
lookup fails or errors on ICMP Destination port field syntax Use type/code in the dst_port field (for example 8/0) with protocol 1; fall back to the GUI Policy Match tool
show counters never move Wrong VDOM, wrong group, or you are looking only at pkts while traffic is offloaded Enter the right VDOM, confirm the group with state, and read asic_pkts
list shows dest(0) or unexpected ranges FQDN unresolved, empty address group, dynamic object with no members diagnose firewall fqdn list-ip, diagnose firewall dynamic list, fix DNS or the connector
“Invalid” or empty output for a group Group ID typo or group not present on this build Group IDs are hex; run diagnose firewall iprope state for the valid list
Hit counts disappeared Someone ran clear with no policy ID Nothing to recover locally; pull historical usage from FortiAnalyzer logs

12. Related Commands

Command Why you would pair it with iprope
diagnose debug flow ... Ground truth for a real packet: routing decision and actual policy hit
diagnose sys session filter policy <id> List live sessions on a policy
diagnose netlink interface list Map zone() indexes to interface names
diagnose firewall proute list Policy routes, the iprope sibling for PBR
diagnose firewall fqdn list-ip Verify FQDN object resolution
diagnose firewall dynamic list Verify dynamic (SDN/EMS/fabric) address membership
diagnose firewall iprope6 ... The IPv6 mirror of every command in this post

13. Quick Reference

# Discover groups on this build
diagnose firewall iprope state

# Compiled entry for forward policy 12
diagnose firewall iprope list 100004 12

# Stats for one or more policies
diagnose firewall iprope show 100004 12 14

# Reset stats (ALWAYS give an ID unless you mean the whole group)
diagnose firewall iprope clear 100004 12

# Which policy will this flow hit?
diagnose firewall iprope lookup 10.0.10.25 0 198.18.40.10 443 6 port5

# Live top 10 by new-session rate
diagnose firewall iprope top 100004 hit-count-rate 5 10

# Local-in table (includes allowaccess-derived entries)
diagnose firewall iprope list 100001

# IPv6 equivalents
diagnose firewall iprope6 lookup <args>
diagnose firewall iprope6 show 100004 12

Bottom line: show firewall policy tells you what you asked for. diagnose firewall iprope tells you what the kernel is doing about it. When those two disagree, the kernel wins every time.

Recent posts

  • If you've spent any time configuring user authentication on... Full Story

  • DNS is one of those technologies that quietly underpins... Full Story

  • BGP issues on FortiGate firewalls usually trace back to... Full Story

  • Every time your laptop talks to your router, a... Full Story

  • If you've spent any time configuring NAT on a... Full Story

  • If you have spent any time configuring firewall policies... Full Story

  • High availability on FortiGate is one of those features... Full Story

  • If you've configured SD-WAN on a FortiGate, you've almost... Full Story

  • FortiLink is the management protocol that turns a FortiSwitch... Full Story

  • FortiSwitches are pretty rock solid from Mean Time Between... Full Story

  • This is a quicky tip.  Have you ever gone... Full Story

  • DNS is one of those quiet pieces of internet... Full Story

  • This article is an updated version of the previous... Full Story

  • You will add ns2 as a secondary (slave) BIND9... Full Story

  • In the process of deploying my lab, I needed... Full Story

  • RFC 8805, used to be known as Self-Correcting IP... Full Story

  • Years back, I wrote an article about certificate pinning. ... Full Story

  • FortiGates have the ability to send alerts to Microsoft... Full Story

  • In this post, I am going to walk through... Full Story

  • Troubleshooting VoIP on a FortiGate can feel like trying... Full Story

  • Prior to FortiOS 7.0, there were three commands to... Full Story

  • In this post, I am going to go over... Full Story

  • What we are going to do:  We are going... Full Story

  • Choosing between FGCP (FortiGate Clustering Protocol) and FGSP (FortiGate... Full Story

  • Creating a VLAN on macOS (The "Pro" Move) A... Full Story

  • This blog post explores the logic behind how macOS... Full Story

  • Pretty Fly for a Wi-Fi Tell My Wi-Fi Love... Full Story

  • Part of my daily gig is creating BoMs (Bill-of-Materials)... Full Story

  • ICMP introduces several security risks, but careful filtering, rate... Full Story

  • The command diag debug application dhcps -1 enables full... Full Story

  • In the world of FortiOS, execute tac report is... Full Story

  • LLDP; What is it The Link Layer Discovery Protocol... Full Story

  • What it actually does When you run diagnose fdsm... Full Story

  • Monkey Bites are bite-sized, high-impact security insights designed for... Full Story

  • I have run macOS in macOS with Parallels but... Full Story

  • Don't be confused with my other FortiNAC posts where... Full Story

  • This is the third session in a multi-part article... Full Story

  • Today I was configuring key-based authentication on a FortiGate... Full Story

  • Netcat, often called the "Swiss Army knife" of networking,... Full Story

  • At its core, IEEE 802.1X is a network layer... Full Story

  • In case you did not see the previous FortiNAC... Full Story

  • This is our 5th session where we are going... Full Story

  • Now that we have Wireshark installed and somewhat configured,... Full Story

  • The Philosophy of Packet Analysis Troubleshooting isn't about looking... Full Story

  • Read, audit, rewrite, and generate FortiOS configuration with two... Full Story

  • Executive Summary Objective: Get HopMatrix installed, verified, and working... Full Story

  • What the kernel actually enforces, how to read it,... Full Story