Pf Configuration Incompatible With — Pf Program Version

If you recently upgraded your kernel via freebsd-update or source compilation, the safest fix is a full reboot:

shutdown -r now

After reboot, both kernel and userland come from the same installed world. Verify:

pfctl -V
sysctl net.pf.version

Load your ruleset:

pfctl -f /etc/pf.conf

Success rate: ~80% for standard FreeBSD upgrades.

The kernel module usually reports its version when loaded. On FreeBSD:

sysctl net.pf.version

Output:

net.pf.version: 1.8.0

On macOS:

sysctl -n kern.version | grep PF

(less direct; often you must check the kernel build date.)

# FreeBSD
kldstat | grep pf

PF caches a compiled binary ruleset, often in /var/db/pf.conf.db or /etc/pf.conf.db. This binary file is version-specific. If this file was created by a newer pfctl and the kernel attempts to read it at boot, you will see the error.

The scrub directive, used for packet normalization, has undergone significant changes.

Furthermore, options like tcp.max-mss have seen syntax adjustments. An older configuration utilizing scrub directives with deprecated parameters (like no-df being handled differently or specific fragment reassembly options) will trigger a parser error, resulting in an incompatibility report. pf configuration incompatible with pf program version

  • Stop packet filtering and clear state:

  • Reload rules:

  • If error persists, reboot system.

  • If still persists, ensure kernel/userland match:

  • If you maintain a custom kernel/module:

  • If you need to revert:

  • For FreeBSD systems, a mismatch often occurs after an incomplete freebsd-update or source upgrade. Fix by completing the upgrade:

    Using freebsd-update:

    freebsd-update fetch
    freebsd-update install
    # Rebuild any third-party modules if necessary
    shutdown -r now
    

    Using source (for advanced users):

    cd /usr/src
    make buildworld
    make buildkernel
    make installkernel
    reboot
    # After reboot:
    make installworld
    

    Create /tmp/test.conf:

    pass out all
    pass in all
    

    Run:

    pfctl -nf /tmp/test.conf
    

    If this fails too → version mismatch. If it passes → your original config uses deprecated syntax.