PF Strange behaviour in PF? (cannot allocate memory) - With 'set limit table-entries 2000000'

I recently got the following error when running service pf reload:

Code:
#service pf reload
/usr/local/etc/pf.conf:36: cannot define table ddos: Cannot allocate memory
pfctl: Syntax error in config file: pf rules not loaded

So I increased and tuned the settings from 1500000 to the following:

set limit table-entries 2000000
net.pf.request_maxcount=2000000

That didn't work, I still got the "cannot allocate memory"-error.
(the table have 750 000 IP addresses, and the number is slowly increasing)

Then I checked the limits with pfctl -sm:

Code:
# pfctl -sm
states hard limit 100000
src-nodes hard limit 10000
frags hard limit 5000
table-entries hard limit 200000 <--- Note the missing zero
anchors hard limit 0
eth-anchors hard limit 0

Note the missing zero, 2000000 becomes 200000?
So after some fiddling, I tried 4500000 (fewer zeros), then it worked.
After running pfctl -sm again, it showed the correct table-entries:

Code:
# pfctl -sm
...
table-entries hard limit  4500000
...

Couldn't pf handle all the zeros from the set limit table-entries settings, or what?
 
I still doesn't get what's causing this.

I have a script running every 15 minutes, adding new DDoS IP addresses, and there still are some sporadic errors about allocating memory.
It doesn't seem to be related to RAM, as adding more RAM to the VPS, doesn't make the errors go away.

Do you think I should file a bug report ?

Excerpt from the script reloading pf:

Code:
Wed Apr 15 03:45:00 CEST 2026 - Adding DDoS addresses to PF table...
Reloading pf rules.
Done adding...

Wed Apr 15 04:00:00 CEST 2026 - Adding DDoS addresses to PF table...
Reloading pf rules.
/usr/local/etc/pf.conf:28: /usr/local/etc/pf.conf:28: cannot define table ddos: Cannot allocate memory
pfctl: Syntax error in config file: pf rules not loaded
Done adding...

Wed Apr 15 04:15:00 CEST 2026 - Adding DDoS addresses to PF table...
Reloading pf rules.
Done adding...

The VPS NEVER reboots without the error.
I need to enable pf when booted.

More people seems to have had these kind of problems in earlier versions: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=260406

Do you think I should file a bug report ?
 
Are you able to monitor RAM/swap etc. at the time of failures? Maybe when it fails there's some extra pressure on RAM/memory, and then when it works later that pressure has eased off enough for the allocation to succeed. Grasping at straws but if you can see any pattern that might help.
 
Are you able to monitor RAM/swap etc. at the time of failures? Maybe when it fails there's some extra pressure on RAM/memory, and then when it works later that pressure has eased off enough for the allocation to succeed. Grasping at straws but if you can see any pattern that might help.
Thanks for your reply, I really appreciate it!

I think you're on right track, I have tried to check, but haven't found anything yet (knowledge somewhat limited), still keep looking 👀

# vmstat -m | grep -E 'pf|Size'

Code:
Type  Use Memory Req Size(s)
pfs_nodes   22  5632   22 256
pfs_vncache    1 16384    1 16384
pfil   14  1536   70 64,128
tcpfunc    1    64    1 64
pf_temp    0     0    2 32
pf_hash    6 13111296    6 2048
pf_ifnet    7  3584 4955 256,2048
pf_osfp 1191 124992 363255 64,128
pf_rule   48 98304 8418 2048
pf   40   640 8326 16,32,1024,2048,4096,8192,16384,32768
pf_table   18 36864 1270 2048

# vmstat -z | grep pf

Code:
pf mtags:               184,      0,       0,       0,       2,   0,   0,   0
pf tags:                104,      0,       0,       0,       0,   0,   0,   0
pf states:              384, 100000,     552,     688,  443843,   0,   0,   0
pf state keys:           88,      0,     552,     782,  887686,   0,   0,   0
pf source nodes:        152,  10000,       0,       0,       0,   0,   0,   0
pf UDP mappings:        104,      0,       0,       0,       0,   0,   0,   0
pf anchors:            1664,2147483647,       8,      13,       8,   0,   0,   0
pf Ethernet anchors:   1240,2147483647,       0,       0,      28,   0,   0,   0
pf table entry counters: 64,      0,       0,       0,       9,   0,   0,   0
pf table entries:       160,7500000,  756567,  756933,217061520,  18,   0,   0
pf frags:               232,      0,       0,       0,       1,   0,   0,   0
pf fragment node:        72,      0,       0,       0,       1,   0,   0,   0
pf frag entries:         40,   5000,       0,       0,       2,   0,   0,   0
pf state scrubs:         40,      0,       0,       0,       0,   0,   0,   0
 
What version are you running?
Note the missing zero, 2000000 becomes 200000?
So after some fiddling, I tried 4500000 (fewer zeros), then it worked.

So, 2 followed by 6 zeros fails, but 45 followed by 5 zeros works? That is a very strange one.
Unless my math is failing 2,000,000 < 4,500,000 so that is very odd.
 
What version are you running?


So, 2 followed by 6 zeros fails, but 45 followed by 5 zeros works? That is a very strange one.
Unless my math is failing 2,000,000 < 4,500,000 so that is very odd.
Yes that's right, but because pf couldn't reload, it couldn't set the new limit, I realize that now.
But the problem persists - and I have no idea what to do.
It might be on my end I'm afraid, since no one having/had these issues.

I have found some reports of similar problems in other FreeBSD versions.
Anyway, I created a bug report, since I can't figure out what's wrong.

This problem is over my pay grade ;)

==> https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=294541
 
There was something relating to bandwidth specification for one of the queues (single case) where the underlying variable was a uint32 and it needed to be a uint64 (I'm paraphrasing). OpenBSD fixed it, it was ported to CURRENT (not sure if it was MFC to anything).

Perhaps this is something similar
 
Maybe poke around over on OpenBSD bug database see if anyone has reported similar. OpenBSD is the genesis of FreeBSD pf, had divergence, but things have been brought a lot closer (I think to make fixes and new features easier to integrate)
 
I have actually find some reports, but many of them have been for 13.x and 14.x, and they often points to a fix that's a couple of years old.
And that fix seems to be included in 15.x. I might need to tune something more, just need to figure out exactly what.

Thanks for your input, I really appreciate it! 🤝
 
  • Like
Reactions: mer
Code:
Wed Apr 15 03:45:00 CEST 2026 - Adding DDoS addresses to PF table...
Reloading pf rules.
Done adding...

Wed Apr 15 04:00:00 CEST 2026 - Adding DDoS addresses to PF table...
Reloading pf rules.
/usr/local/etc/pf.conf:28: /usr/local/etc/pf.conf:28: cannot define table ddos: Cannot allocate memory
pfctl: Syntax error in config file: pf rules not loaded
Done adding...

Wed Apr 15 04:15:00 CEST 2026 - Adding DDoS addresses to PF table...
Reloading pf rules.
Done adding...

"Syntax error" looks strange... Is script just replacing persistent table from some file (-T replace -f "...")?
 
"Syntax error" looks strange... Is script just replacing persistent table from some file (-T replace -f "...")?
The shell script is just doing a service pf reload after adding new ips - I'm not sure if it's replacing or flushing the already loaded <ddos> table.

This is what I have (if there are any errors):

Code:
### SET PARAMS
ext_if="vmx0"
me="000.000.000.000"
good_tcp_ports="{443,80}"

### ADDED FOR USING DDoS TABLE
set limit table-entries 7500000

### REASSEMBLE FRAGMENTET PACKETS
scrub in on $ext_if all fragment reassemble

### DO NOTHING WITH LOOPBACK
set skip on lo0

### RESET ALL RULES
block in all
block out all

### BLOCK SPOOKS
antispoof for lo0
antispoof for $ext_if inet
block in from no-route to any
block in from urpf-failed to any
block in quick on $ext_if from any to 255.255.255.255
block in quick log on $ext_if from { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 255.255.255.255/32 } to any

### DDoS
table <ddos> persist file "/usr/local/etc/pf.ddos.list"
block in quick from <ddos> to any

### WHITELIST
table <whitelist> persist file "/usr/local/etc/pf.whitelist"
pass in quick from <whitelist> to any

### BLACKLIST
table <blacklist> persist file "/usr/local/etc/pf.blacklist"
block in quick from <blacklist> to any

### SSH GUARD
table <sshguard> persist
block in quick from <sshguard>

### BLOCK ALL IPV6
block in quick inet6 all
block out quick inet6 all

### BLOCK IN AND OUT ON PORT 0
block quick proto { tcp, udp } from any port = 0 to any
block quick proto { tcp, udp } from any to any port = 0

### OPEN TCP SERVER SERVICES
pass in quick on $ext_if inet proto tcp from any to $me port $good_tcp_ports

### Fail2ban
anchor "f2b/*"

### RUN ALL RULES
pass out quick on $ext_if inet proto { tcp, udp, icmp } from $me to any modulate state
 
Back
Top