Wazuh fix note · rule loading

Wazuh rule dropped at load: warnings 7617 and 7619, while analysisd -t exits 0

Your child rule sits in a file whose name sorts before the file of its if_sid parent. Custom and stock rule files are loaded together in order of full file name, so when your rule is read the parent does not exist yet. Wazuh logs 7617 and 7619, ignores the rule, and the config check still exits 0.

Dong Nguyen, ATK New Technology · 28 September 2026 · measured on Wazuh 4.14.7 unless stated otherwise


How to check in one minute

Run the config check and read its output instead of trusting the exit code. It reads the rules again, so it works at any time, with no restart:

/var/ossec/bin/wazuh-analysisd -t 2>&1 | grep -E '\((7617|7619)\)'

Each 7619 line is one rule Wazuh will ignore; grep -c '(7619)' gives the count. A 7617 on its own only says one parent is missing: a rule with several if_sid parents still loads if one of them exists (on 4.14.7, a rule with parents 910010, 5715 printed 7617 for the missing one and kept running).

The same lines go to /var/ossec/logs/ossec.log at each restart, but that file rotates daily, so an empty grep there does not prove the rules loaded.

This is what the two lines look like, word for word:

WARNING: (7617): Signature ID '5715' was not found and will be ignored in the 'if_sid' option of rule '100080'.
WARNING: (7619): Empty 'if_sid' value. Rule '100080' will be ignored.

Every rule ID in a 7619 line is a rule that is not running. The 7617 line next to it names the parent it was waiting for.

Why it happens

We used one test rule, a child of the stock sshd rule 5715, which lives in /var/ossec/ruleset/rules/0095-sshd_rules.xml:

<group name="test,">
  <rule id="100080" level="9">
    <if_sid>5715</if_sid>
    <match>Accepted password</match>
    <description>test child of 5715</description>
  </rule>
</group>

We put the same rule in five differently named files in /var/ossec/etc/rules/, ran wazuh-analysisd -t, restarted the manager, and sent one line through wazuh-logtest:

sshd[1234]: Accepted password for root from 203.0.113.5 port 22 ssh2
file in etc/rules-t exit7617 / 7619logtest lands on
0094-test.xml0yes5715 level 3, our rule ignored
0096-test.xml0no100080 level 9, fires
local_rules.xml0no100080, fires
0095-aaa.xml0yes5715, our rule ignored
0095-zzz.xml0no100080, fires

Files in etc/rules are not loaded after the stock ruleset. They are merged with ruleset/rules and loaded in order of the full file name. The last two rows show it: 0095-aaa.xml sorts before 0095-sshd_rules.xml, so 5715 does not exist yet when our rule is read. 0095-zzz.xml sorts after it, and the same rule fires.

local_rules.xml is safe for this reason: the 4.14.7 image has 168 stock rule files, all 168 start with a digit, and the last is 0999-malicious-ioc-rules.xml. A name that starts with a letter loads after all of them.

The trap is the config check. wazuh-analysisd -t exited 0 in all five cases. It prints the warnings, but a warning is not a failure, so a deploy script that checks only the exit code carries on, and the manager starts cleanly with one rule fewer than you think.

Fix

Move the child rule into a file whose name sorts after the file that holds its parent:

To find the parent's file:

grep -l 'id="5715"' /var/ossec/ruleset/rules/*.xml /var/ossec/etc/rules/*.xml

Then run the check again, confirm the 7619 line is gone, and confirm that wazuh-logtest shows your rule ID, not the parent's. The full write-up is on dev.to.

Limits of what we measured

One Wazuh release (4.14.7), one single-node manager in a throwaway container, one parent rule (5715), and only if_sid. We have not measured if_matched_sid, if_group, decoders, or a cluster. If you run a cluster, check for the warnings on every node. Francisco Sousa found the file-name part of this in his own container before we did; our runs confirmed it.

Free check

Check your whole manager for this and other silent rules: Rule Doctor Lite (free, read-only, one Python file).

Lite labels these rules DROPPED-AT-LOAD, from the 7617/7619 lines in ossec.log or from the load order. Tested on a 4.14.7 manager with the same rule in 0094-test.xml (dropped) and in 0500-ok.xml (fired).

curl -sLO https://github.com/xuxu298/rule-doctor-lite/releases/latest/download/rule-doctor-lite.py
sudo python3 rule-doctor-lite.py

Or have it fixed for you.