Wazuh custom rule does not trigger: start with the real event
Before changing rule logic repeatedly, test custom rules with real log samples and confirm the matched decoder or base rule.
Published · Updated
Problem
A custom Wazuh rule is deployed, but no alert is generated.
Why it happens
The incoming log may not match the expected decoder, field, base rule ID, or pattern.
Recommended approach
Capture the exact event received by Wazuh, run it through wazuh-logtest, and verify each stage: decoding, extracted fields, base rule, and custom rule conditions. Change one assumption at a time.
Verification order
Useful checks:
- Confirm the event reaches the manager
- Test the exact event with
/var/ossec/bin/wazuh-logtest - Record the matched decoder and extracted field names
- Confirm the parent or base
rule.id - Inspect
/var/ossec/logs/alerts/alerts.jsonafter deployment
Use this when
- Suppression rules
- Custom detections
- ClamAV or YARA rules
- Application logs
- Wazuh tuning
Avoid this when
- When the log is not collected by the agent at all
Capture the event Wazuh actually receives
Do not rebuild the log from memory. Copy one complete event from the agent or manager logs, preserving its timestamp, program name, JSON structure, and field names. wazuh-logtest processes one-line events, so compact multiline JSON first.
bash
sudo /var/ossec/bin/wazuh-logtest -vPaste the event and inspect all three phases:
- Pre-decoding: program name, timestamp, and hostname
- Decoding: decoder name and extracted fields
- Rule matching: rule ID, level, groups, and description
If Phase 2 does not expose the field referenced by the rule, changing the rule condition will not help; fix or select the decoder first.
Minimal custom-rule example
Store custom rules under /var/ossec/etc/rules/, not the packaged ruleset directory:
xml
<group name="local,application,">
<rule id="100100" level="7">
<decoded_as>json</decoded_as>
<field name="event.action">login_failed</field>
<description>Application login failed</description>
</rule>
</group>Use an ID in your organization’s custom range and confirm the decoded field is exactly event.action. Field paths and values are case-sensitive where the decoder and rule engine treat them as such.
Parent-rule failures
Rules using <if_sid>, <if_group>, or frequency correlation depend on another match. Confirm the real event fires that parent rule in the same test session.
xml
<rule id="100101" level="10" frequency="5" timeframe="60">
<if_matched_sid>100100</if_matched_sid>
<same_srcip />
<description>Repeated application login failures</description>
</rule>Feed repeated samples into the same wazuh-logtest session when testing frequency, timeframe, or if_matched_sid behavior.
Apply and verify the deployed rule
Saving a rule is enough for a new wazuh-logtest session to load it, but the Wazuh manager must be restarted before the live analysis engine generates alerts with the change:
bash
sudo systemctl restart wazuh-manager
sudo journalctl -u wazuh-manager -n 100 --no-pager
sudo tail -f /var/ossec/logs/alerts/alerts.jsonValidate the XML and watch manager startup logs for duplicate rule IDs, invalid elements, or files that failed to load.