Wazuh fix note · agent events

Wazuh rule with <hostname> matches in wazuh-logtest but never fires for agent events

For an event that comes from an agent, analysisd sets the host name to the agent name before rules run, so <hostname> is compared with that name. The alert still shows the syslog host under predecoder.hostname, which is why the rule looks like it should have matched. wazuh-logtest treats a pasted line as a local event, keeps the syslog host, and matches, so the test passes and production does not.

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

Stuck on this right now? Email your custom rules or decoders, one sample log line and your Wazuh version to support@atkvn.com. We run them on that exact version and reply within 24 hours with what we find. Free. Remove hostnames, IPs and usernames first. Rather not send them? Run the free pre-check in your browser; your files never leave your machine.

USD 49 is for one fix, in exchange for an anonymised write-up we can publish. After that: USD 149 per problem, paid only after it works on your system.


How to check in one minute

Run your line through wazuh-logtest the way analysisd sees an agent event, by passing an agent-style location. Use your agent's ID, name and IP, and the location the event comes from:

/var/ossec/bin/wazuh-logtest -l '[002] (cae) 192.168.8.28->journald'

Paste the log line. If your rule matched with the default location (stdin) but not with this one, the host name condition is the cause.

Why it happens

Every event reaches analysisd with a location. A local event has a location like stdin or a file path; an event from an agent has one that starts with the agent ID, like [002] (cae) 192.168.8.28->journald. In the 4.14.7 source (src/analysisd/cleanevent.c, around lines 543–584), a location that starts with [ makes analysisd take the text between the parentheses, the agent name, as the event's host name. For a local event it keeps the host name read from the syslog header.

<hostname> in a rule is compared with that value (rules.c, around lines 2875–2880), as an OS_Match expression by default. The predecoder.hostname in the alert JSON is parsed again from full_log when the alert is written (json_extended.c), so it shows the syslog host even when the rule compared against the agent name.

We checked it on a 4.14.7 manager with one su line whose syslog host is DN4, a parent rule reached on every run, and two children: one with <hostname>DN4</hostname>, one with <hostname>^cae$</hostname>.

wazuh-logtest -l<hostname>DN4</hostname><hostname>^cae$</hostname>
stdin (default, local event)firesdoes not fire
[002] (cae) 192.168.8.28->journalddoes not firefires
[002] (caesar) 192.168.8.29->journalddoes not firedoes not fire

In all three runs logtest printed hostname: 'DN4' in its decoding phase. The value it prints is not the value the rule compares.

Fix

Limits of what we measured

One release (4.14.7), one single-node throwaway manager, one su line, tested with wazuh-logtest and an agent-style location. We did not send a journald event through a real agent; the live behaviour matches a user report on wazuh/wazuh#39536, where a <hostname> step stopped every event from an agent named cae on two nightly runs. <location> was read from the source, not measured. Events that reach the manager over syslog (<remote>) rather than from an agent are not covered here. Wazuh 4.14.8 (released 25 September 2026) ships byte-identical source files for rule loading and matching (rules-config.c, rules.c, cleanevent.c, logmsg.h, list_op.c); we compared the files, we did not rerun the tests on 4.14.8.

Free check

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

Lite does not read rule conditions: a rule stopped by <hostname> shows as NO-MATCH, a rule that never matched anything. Send us your rule file and the free 24-hour answer names this cause when it is the one.

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

Free answer within 24 hours.

Paste the rule, config or a few sample lines below, with hostnames and IPs removed. We reply within 24 hours with what is wrong. If you want us to fix it: USD 149 per problem, paid only after it works on your system.

Or email support@atkvn.com.