{"id":5519,"date":"2026-09-26T04:01:16","date_gmt":"2026-09-26T07:01:16","guid":{"rendered":"https:\/\/tucumandevelopers.com\/index.php\/2026\/09\/26\/wazuh-custom-rule-never-fires-and-analysisd-t-still-exits-0-the-file-name-decides\/"},"modified":"2026-09-26T04:01:16","modified_gmt":"2026-09-26T07:01:16","slug":"wazuh-custom-rule-never-fires-and-analysisd-t-still-exits-0-the-file-name-decides","status":"publish","type":"post","link":"https:\/\/tucumandevelopers.com\/index.php\/2026\/09\/26\/wazuh-custom-rule-never-fires-and-analysisd-t-still-exits-0-the-file-name-decides\/","title":{"rendered":"Wazuh custom rule never fires, and analysisd -t still exits 0: the file name decides"},"content":{"rendered":"<div>\n<div><\/div>\n<p><code>5715<\/code> lives in <code>\/var\/ossec\/ruleset\/rules\/0095-sshd_rules.xml<\/code>. We put the same rule in five differently named files in <code>\/var\/ossec\/etc\/rules\/<\/code>, ran <code>wazuh-analysisd -t<\/code>, restarted, and sent one line through <code>wazuh-logtest<\/code>: <\/p>\n<div>\n<pre><code><span>Sep 26 10:00:00 host1 sshd[1234]: Accepted password for root from 203.0.113.5 port 22 ssh2 <\/span><\/code><\/pre>\n<div>\n<\/p><\/div>\n<\/p><\/div>\n<div>\n<table>\n<thead>\n<tr>\n<th>file<\/th>\n<th> <code>-t<\/code> exit<\/th>\n<th>7617 \/ 7619 warnings<\/th>\n<th>logtest lands on<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>0094-test.xml<\/code><\/td>\n<td>0<\/td>\n<td>yes<\/td>\n<td> <code>5715<\/code> (our rule ignored)<\/td>\n<\/tr>\n<tr>\n<td><code>0096-test.xml<\/code><\/td>\n<td>0<\/td>\n<td>no<\/td>\n<td> <code>100080<\/code> (fires)<\/td>\n<\/tr>\n<tr>\n<td><code>local_rules.xml<\/code><\/td>\n<td>0<\/td>\n<td>no<\/td>\n<td> <code>100080<\/code> (fires)<\/td>\n<\/tr>\n<tr>\n<td><code>0095-aaa.xml<\/code><\/td>\n<td>0<\/td>\n<td>yes<\/td>\n<td> <code>5715<\/code> (our rule ignored)<\/td>\n<\/tr>\n<tr>\n<td><code>0095-zzz.xml<\/code><\/td>\n<td>0<\/td>\n<td>no<\/td>\n<td> <code>100080<\/code> (fires)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>The two warnings, word for word: <\/p>\n<div>\n<pre><code>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. <\/code><\/pre>\n<div>\n<\/p><\/div>\n<\/p><\/div>\n<h2> <a name=\"what-it-means\" href=\"#what-it-means\"> <\/a> What it means <\/h2>\n<p>Files in <code>etc\/rules<\/code> are not loaded after the stock ruleset. They are merged with <code>ruleset\/rules<\/code> and loaded in order of the <strong>full file name<\/strong>. The last two rows show it: <code>0095-aaa.xml<\/code> sorts before <code>0095-sshd_rules.xml<\/code>, so when our rule is read, <code>5715<\/code> does not exist yet and the rule is dropped. <code>0095-zzz.xml<\/code> sorts after it, and the same rule fires.<\/p>\n<p><code>local_rules.xml<\/code> is safe for this reason: letters sort after digits, and all 168 stock rule files in 4.14.7 start with a digit (<code>0010<\/code> to <code>0999<\/code>), so it loads after every one of them.<\/p>\n<p>The trap is the config check. <code>wazuh-analysisd -t<\/code> exits 0 in all five cases. It prints the two warnings, but a warning is not a failure, and nothing in a deploy script that checks the exit code will stop. The manager then starts cleanly with one rule fewer than you think.<\/p>\n<h2> <a name=\"check-yours-in-a-minute\" href=\"#check-yours-in-a-minute\"> <\/a> Check yours in a minute <\/h2>\n<p>After a restart, the warnings are also in the manager log: <\/p>\n<div>\n<pre><code><span>grep<\/span> <span>-E<\/span> <span>'\\((7617|7619)\\)'<\/span> \/var\/ossec\/logs\/ossec.log <\/code><\/pre>\n<div>\n<\/p><\/div>\n<\/p><\/div>\n<p>Every rule id you see in a 7619 line is a rule that is not running. The 7617 line on the same second tells you which parent it was waiting for.<\/p>\n<p>Before a restart, run the check yourself and read its output instead of trusting the exit code: <\/p>\n<div>\n<pre><code>\/var\/ossec\/bin\/wazuh-analysisd <span>-t<\/span> 2&gt;&amp;1 | <span>grep<\/span> <span>-E<\/span> <span>'\\((7617|7619)\\)'<\/span> <\/code><\/pre>\n<div>\n<\/p><\/div>\n<\/p><\/div>\n<p>For a single rule, <code>wazuh-logtest<\/code> with a real sample line is the final word: if the output shows the parent&#8217;s id and not yours, your rule did not load or did not match.<\/p>\n<h2> <a name=\"the-fix\" href=\"#the-fix\"> <\/a> The fix <\/h2>\n<p>Move the child rule into a file whose name sorts <strong>after<\/strong> the file that holds its parent:<\/p>\n<ul>\n<li>put it in <code>local_rules.xml<\/code>, or<\/li>\n<li>give your file a prefix above the parent&#8217;s file (<code>0096-...<\/code> or higher for children of sshd rules), or a name that starts with a letter.<\/li>\n<\/ul>\n<p>To find the parent&#8217;s file: <\/p>\n<div>\n<pre><code><span>grep<\/span> <span>-l<\/span> <span>'id=\"5715\"'<\/span> \/var\/ossec\/ruleset\/rules\/<span>*<\/span>.xml \/var\/ossec\/etc\/rules\/<span>*<\/span>.xml <\/code><\/pre>\n<div>\n<\/p><\/div>\n<\/p><\/div>\n<p>Then run the check again and confirm the 7619 line is gone, and that logtest lands on your rule.<\/p>\n<h2> <a name=\"what-we-did-not-measure\" href=\"#what-we-did-not-measure\"> <\/a> What we did not measure <\/h2>\n<p>One Wazuh version (4.14.7), a single manager, one parent rule, and only <code>if_sid<\/code>. We did not test <code>if_matched_sid<\/code>, <code>if_group<\/code>, decoders, or a cluster. If you run a cluster, check the warnings on every node.<\/p>\n<p>Credit to Francisco Sousa, who found the file name half of this in his own container before we did.<\/p>\n<hr>\n<p><em>If one of your rules loads and never fires and you would rather not dig into it yourself, send us the rule, your Wazuh version and a sample event: we find why, then write and test the fix on that version. USD 490 per rule case, paid only after it runs clean on your side. <a href=\"https:\/\/vct.atkvn.com\/#fix-pack\" target=\"_blank\" rel=\"noopener noreferrer\">vct.atkvn.com\/#fix-pack<\/a><\/em><\/p>\n<p><em>Dong Nguyen, ATK New Technology<\/em><\/p>\n<\/p><\/div>\n<\/div>\n<\/div>\n<\/div>\n<p>Fuente: <a href=\"https:\/\/dev.to\/xuxu298\/wazuh-custom-rule-never-fires-and-analysisd-t-still-exits-0-the-file-name-decides-58od\">Art\u00edculo original<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>5715 lives in \/var\/ossec\/ruleset\/rules\/0095-sshd_rules.xml. We put the same rule in five differently named files in \/var\/ossec\/etc\/rules\/, ran wazuh-analysisd -t, restarted, and sent one line through wazuh-logtest: Sep 26 10:00:00 host1 sshd[1234]: Accepted password for root from 203.0.113.5 port 22 ssh2 file -t exit 7617 \/ 7619 warnings logtest lands on 0094-test.xml 0 yes 5715 (our [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":5518,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"webixso_pending_account_ids":""},"categories":[41],"tags":[],"class_list":["post-5519","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devto"],"jetpack_publicize_connections":[],"_links":{"self":[{"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/posts\/5519","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/comments?post=5519"}],"version-history":[{"count":0,"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/posts\/5519\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/media\/5518"}],"wp:attachment":[{"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/media?parent=5519"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/categories?post=5519"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tucumandevelopers.com\/index.php\/wp-json\/wp\/v2\/tags?post=5519"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}