Troubleshooting wazuh-logtest: Why Alerts Are Missing from JSON Output

When building or troubleshooting detection logic in Wazuh, wazuh-logtest is one of the most valuable diagnostic tools available.

It allows administrators to simulate how Wazuh processes incoming log events without waiting for live data to arrive from monitored endpoints.

By feeding sample logs into the analysis engine, you can verify whether decoders correctly parse fields and whether rules generate the expected security alerts before deploying changes to production.

One of the more confusing issues administrators encounter is when the alerts field is missing from the JSON output.

At first glance, the log may appear to have been processed successfully, yet the expected alert information never appears.

This often leads users to believe that wazuh-logtest is malfunctioning when the real cause is typically related to rule evaluation, decoder matching, configuration settings, or the specific command-line options being used.

Without the alerts field, validating detection logic becomes significantly more difficult.

Security teams cannot easily confirm whether a custom rule fired, whether an event reached the configured alert level, or whether changes to decoders produced the intended results.

This uncertainty can delay deployments and increase the risk of production rules silently failing to detect malicious activity.

In this guide, you’ll learn how wazuh-logtest generates alerts internally, why the alerts field may disappear from JSON output, how to systematically troubleshoot each stage of the processing pipeline, and the best practices for ensuring your custom decoders and rules generate consistent, testable results.

Resources:

Wazuh documentation on log testing: https://documentation.wazuh.com/current/user-manual/ruleset/testing.html

Related Guide:

How to Test Wazuh Rules


What Is wazuh-logtest?

wazuh-logtest is a command-line utility included with the Wazuh manager that allows administrators to manually submit log events to the Wazuh analysis engine.

Instead of waiting for agents to forward real-world events, the tool processes sample logs immediately, making it invaluable for developing custom decoders, testing detection rules, and troubleshooting parsing issues.

Unlike simply inspecting log files, wazuh-logtest executes the same analysis pipeline used by the Wazuh manager.

This means it evaluates:

  • Decoders
  • Rule inheritance
  • Rule chaining
  • Field extraction
  • Alert generation logic

Because the tool follows the actual detection workflow, it provides an accurate preview of how Wazuh will treat a log once it reaches production.

Purpose of the Tool

The primary goal of wazuh-logtest is to validate detection logic before deployment.

Security teams commonly use it to:

  • Test custom decoders
  • Verify regex patterns
  • Confirm extracted fields
  • Debug rule inheritance
  • Validate rule IDs
  • Test alert levels
  • Confirm MITRE ATT&CK mappings
  • Verify JSON output before deploying configuration changes

Using wazuh-logtest dramatically reduces troubleshooting time because you can repeatedly test the same log entry without generating actual events on monitored systems.

Related Guide: Custom Decoder Isn’t Matching: Wazuh Logtest Deep Dive

How It Processes Logs

When a log is submitted, wazuh-logtest sends it through the same internal processing stages used by the Wazuh analysis daemon (analysisd).

The tool attempts to:

  1. Normalize the raw log
  2. Match a decoder
  3. Extract fields
  4. Evaluate every applicable rule
  5. Generate alerts if rule conditions are satisfied
  6. Produce structured output (including JSON when requested)

Because every stage depends on the previous one succeeding, an error early in the pipeline, such as a decoder failing to match, can prevent alert generation entirely.

Relationship Between Decoders, Rules, and Alerts

Understanding the relationship between these three components is essential when troubleshooting missing alerts.

Decoders identify the log format and extract meaningful fields from the raw message.

For example, a decoder might extract:

  • source IP
  • username
  • process name
  • event ID
  • file path

These extracted fields are then evaluated against rules.

Rules determine whether:

  • suspicious activity occurred
  • thresholds were exceeded
  • compliance requirements were met
  • an alert should be created

Only after a rule successfully matches does Wazuh create an alert object.

If no rule fires, or if every matching rule has an alert level below the configured threshold, the JSON output may not contain an alerts section.

Typical JSON Output Structure

When everything works correctly, JSON output typically contains several sections describing how the event was processed.

Common objects include:

  • Input log
  • Decoder information
  • Extracted fields
  • Matching rules
  • Alert metadata
  • Rule level
  • Description
  • Groups
  • MITRE ATT&CK mappings (when applicable)

If the alerts object is missing, it usually indicates that the processing pipeline completed without producing an alert rather than indicating a failure of wazuh-logtest itself.

The official Wazuh documentation recommends using log testing to verify both decoder extraction and rule matching before deploying configuration changes.


How Wazuh Generates Alerts During Log Testing

Understanding how Wazuh internally creates alerts makes troubleshooting much easier.

The detection engine follows a sequential pipeline where each phase depends on the previous one.

If any stage fails, the final JSON output may omit the alerts field entirely.

Phase 1: Log Collection

Everything begins when wazuh-logtest receives a raw log entry.

Unlike events received from an agent, the log is manually submitted through the testing interface.

The analysis engine then treats this input as though it had arrived from a monitored endpoint.

Before any detection occurs, Wazuh performs basic preprocessing, such as:

  • Normalizing the log
  • Determining the log format
  • Preparing the event for decoder matching

If the input log is malformed or incomplete, later stages may never execute correctly.

Phase 2: Decoder Matching

The next step is identifying which decoder can interpret the log.

Decoders act as parsers that recognize known log formats and extract structured fields.

During this phase Wazuh attempts to identify:

  • Program name
  • Timestamp
  • Username
  • Source IP
  • Destination IP
  • Process name
  • Event identifiers
  • File paths
  • Custom fields

If no decoder matches, rule evaluation becomes extremely limited because most rules rely on extracted fields rather than raw log text.

This is one of the most common reasons administrators later discover that no alerts appear in the JSON output.

Related Guide: How to Fix “Field Already Defined” Syntax Errors in Wazuh Decoders

Phase 3: Rule Evaluation

After decoding, Wazuh begins evaluating its ruleset.

Each rule checks specific conditions, including:

  • Decoder name
  • Parent rule inheritance
  • Extracted field values
  • Regular expression matches
  • Frequency thresholds
  • Time windows
  • Event correlation
  • Previous rule matches

Rules are evaluated in order, with child rules inheriting conditions from parent rules where applicable.

Only rules whose conditions evaluate to true are considered successful matches.

One important design principle emphasized by the Wazuh engineering team is that decoders extract information, while rules make detection decisions.

Keeping these responsibilities separate improves maintainability and reduces false positives.

Wazuh Rules Syntax Reference: https://documentation.wazuh.com/current/user-manual/ruleset/rules/index.html

Phase 4: Alert Creation

If one or more rules match successfully, Wazuh determines whether an alert should actually be generated.

Several factors influence alert creation, including:

  • Rule level
  • noalert settings
  • Rule suppression
  • Correlation logic
  • Frequency requirements
  • Ignore intervals
  • Child rule behavior

A rule can technically match without producing an alert.

For example:

  • Rules configured with <noalert>1</noalert>
  • Informational parent rules
  • Correlation rules awaiting additional events
  • Rules below configured alert thresholds

These situations commonly explain why users see successful decoder matches but no alerts object in JSON output.

Phase 5: JSON Output Generation

Finally, wazuh-logtest serializes the processing results into JSON.

Depending on what occurred during evaluation, the output may contain:

  • Input event information
  • Decoder metadata
  • Extracted fields
  • Matching rules
  • Alert information
  • Rule descriptions
  • Groups
  • Compliance mappings
  • MITRE ATT&CK techniques

If no alert object was created during Phase 4, the resulting JSON simply omits the alerts field.

This behavior is expected and generally indicates that Wazuh completed processing successfully but determined that the event did not produce an alert under the current ruleset, rather than indicating a software defect.

Independent security practitioners and experienced Wazuh users frequently recommend tracing the event through each processing phase, decoder, rule match, and alert generation, to isolate where the pipeline stops, rather than assuming the JSON serializer is at fault.


Symptoms of Missing Alerts in JSON Output

When the alerts field is absent from wazuh-logtest JSON output, the issue is rarely the JSON formatter itself.

Instead, it usually indicates that the event successfully passed through part of the analysis pipeline but failed to meet the requirements for alert generation.

Recognizing the symptoms can help you determine where processing stops and significantly reduce troubleshooting time.

JSON Output Contains Decoded Fields but No alerts Object

One of the most common scenarios is seeing output similar to:

  • Decoder information is present
  • Extracted fields appear correctly
  • Rule metadata may be partially populated
  • The alerts object is completely missing

This generally means the decoder successfully parsed the log, but no rule ultimately generated an alert.

In other words:

Raw Log
    ↓
Decoder ✓
    ↓
Fields Extracted ✓
    ↓
Alert Generated ✗

This is an important clue because it immediately narrows the investigation to the rule evaluation stage rather than decoder troubleshooting.

Log Matches a Decoder but Triggers No Rule

A successful decoder match does not guarantee alert generation.

For example, a decoder may correctly extract:

  • username
  • source IP
  • process name
  • event ID

However, if no rule references those extracted fields, or if none of the rule conditions evaluate to true, the processing pipeline ends without producing an alert.

This often happens after creating a new decoder but forgetting to write the corresponding custom rule.

Rule Evaluation Stops Unexpectedly

Sometimes rule evaluation appears to terminate earlier than expected.

Common indicators include:

  • Parent rule matches
  • Child rule never executes
  • Correlation rules never activate
  • Later rules are skipped

This typically points to problems with:

  • if_sid
  • if_group
  • rule inheritance
  • missing prerequisite conditions

Since many Wazuh rules build upon previous rule matches, breaking the dependency chain prevents downstream alerts from being created.

Expected Alert Level Is Missing

You may expect a level 10 alert but instead receive:

  • no alert
  • level 0 processing
  • informational output only

This usually indicates that:

  • another rule matched first
  • rule conditions were only partially satisfied
  • the expected rule never executed
  • a parent rule prevented child evaluation

Always verify which rule actually matched instead of assuming the intended rule fired.

Custom Rules Appear to Be Ignored

A particularly frustrating symptom occurs when custom rules seem to have no effect at all.

Typical signs include:

  • Rule never appears during testing
  • Built-in rules continue matching instead
  • Configuration changes produce no difference
  • Restarting Wazuh changes nothing

In many cases, the rule file was never loaded because of:

  • XML syntax errors
  • incorrect file location
  • duplicate rule IDs
  • missing <include> statements

Successful Parsing Without Alert Generation

Perhaps the most misleading symptom is when everything appears to work correctly.

The log:

  • parses successfully
  • extracts fields correctly
  • completes processing
  • returns valid JSON

Yet no alert exists.

This is actually normal behavior whenever no rule generates an alert.

The absence of parsing errors should not be interpreted as confirmation that your detection logic is working.


Common Causes of Missing Alerts in wazuh-logtest

Once you’ve confirmed that the alerts object is missing, the next step is determining why Wazuh decided not to create one.

The following are the most common root causes encountered when testing custom rules and decoders.

No Matching Rule Exists

The decoder may successfully identify and parse the log, but Wazuh still requires at least one rule to match before generating an alert.

This often occurs when administrators:

  • create a custom decoder
  • test vendor-specific logs
  • add new log sources
  • forget to create corresponding detection rules

Without a matching rule, Wazuh has no basis for creating an alert.

Rule Level Is Set to Zero

Rules configured with:

<rule id="100500" level="0">

are intentionally non-alerting.

Level 0 rules are commonly used for:

  • preprocessing
  • categorization
  • parent rule inheritance
  • event normalization

Although they participate in rule evaluation, they do not normally generate alerts themselves.

Administrators frequently mistake successful level 0 matches for missing alerts when the behavior is actually expected.

Rule Conditions Are Not Met

Even if the correct rule exists, every condition within that rule must evaluate successfully.

Common reasons include:

Missing Fields

A decoder may fail to extract a required field such as:

  • username
  • srcip
  • process
  • event_id

Without that field, dependent rule conditions fail automatically.

Incorrect Field Values

Rules often expect exact values.

For example:

action = denied

will not match:

action = deny

Even small differences in capitalization, spacing, or punctuation can prevent rule execution.

Failed Regex Conditions

Many Wazuh rules rely on regular expressions.

Examples of common regex problems include:

  • overly restrictive patterns
  • missing escape characters
  • unexpected whitespace
  • different log formatting
  • vendor firmware updates changing log structure

When a regex fails, the rule simply does not match.

Decoder Failed to Extract Required Fields

Successful decoder matching does not necessarily mean every required field was extracted correctly.

Several decoder problems commonly prevent downstream rule execution.

Incorrect Decoder Order

Wazuh evaluates decoders sequentially.

A generic decoder may match before a more specific decoder, preventing the intended decoder from ever running.

Missing <order> Entries

The <order> tag determines which captured regex groups become named fields.

Missing or incorrect <order> entries leave important values unavailable for later rule evaluation.

Regex Mismatches

Minor log format changes frequently break decoder regex patterns.

Examples include:

  • additional spaces
  • reordered fields
  • new timestamps
  • vendor software updates
  • optional values becoming mandatory

If the decoder extracts incomplete data, subsequent rules often fail.

Parent Rule Dependencies Not Satisfied

Many Wazuh rules inherit conditions from parent rules.

For example:

Parent Rule
      ↓
Child Rule
      ↓
Alert

If the parent rule never matches, the child rule is never evaluated.

Always verify:

  • if_sid
  • parent IDs
  • inheritance chain
  • prerequisite rule matches

Incorrect Rule Group Configuration

Rules frequently depend on group membership.

For example:

<if_group>authentication</if_group>

If the decoder or earlier rule assigns a different group than expected, the dependent rule never executes.

Group mismatches are especially common after modifying built-in rules or creating custom rulesets.

Custom Rules Are Not Loaded

Sometimes the rule itself is perfectly valid but never becomes part of the running ruleset.

Common causes include:

File Location Issues

The rule file is placed outside the directory Wazuh loads during startup.

XML Syntax Errors

Even a single malformed XML tag can prevent an entire rule file from loading.

Check startup logs carefully for parsing errors.

Rule File Not Included

If the custom XML file is never referenced in the configuration, Wazuh simply ignores it.

Always verify that your custom rules are included and successfully loaded after restarting the manager.

Related Guide:

How to Test Wazuh Rules

Rule ID Conflicts

Every Wazuh rule requires a unique rule ID.

Duplicate IDs can cause:

  • rules being overridden
  • unexpected behavior
  • inconsistent testing results
  • different rules loading than expected

Always maintain a unique custom rule ID range to avoid collisions with built-in rules.

Testing the Wrong Log Format

A surprisingly common mistake is testing logs that differ from the ones received in production.

Differences may include:

  • missing prefixes
  • altered timestamps
  • copied console output
  • removed metadata
  • different whitespace

Even seemingly insignificant formatting differences can prevent decoders and rules from matching.

Whenever possible, test with raw logs captured directly from production.

Wazuh Version Differences

Rule behavior can change between Wazuh releases.

Examples include:

  • updated built-in decoders
  • modified default rules
  • renamed fields
  • improved regex patterns
  • deprecated rule logic

If a rule worked in an older release but not after an upgrade, compare the bundled rulesets and release notes before assuming your configuration is incorrect.

Wazuh Release Notes: https://documentation.wazuh.com/current/release-notes/index.html


How to Diagnose Missing Alerts Step by Step

A structured troubleshooting approach is far more effective than randomly modifying decoders or rules.

The following workflow follows the same order that Wazuh processes events internally, allowing you to isolate exactly where alert generation stops.

Step 1: Verify Decoder Matching

Begin by confirming that the correct decoder processes the log.

Check:

  • decoder name
  • extracted fields
  • captured values
  • regex matches

If the wrong decoder matches, or no decoder matches at all, rule evaluation is unlikely to succeed.

Compare the extracted fields against what your rules expect.

Step 2: Confirm Rule Matching

Next, determine which rule should generate the alert.

Review:

  • rule ID
  • matching conditions
  • required fields
  • regex expressions
  • if_sid
  • if_group

Walk through each condition individually and verify that the decoded event satisfies every requirement.

Don’t assume the intended rule is being evaluated, confirm it.

Step 3: Inspect Rule Level

Once you’ve identified the matching rule, verify its severity level.

Ensure:

  • level is greater than zero
  • noalert is not enabled
  • suppression settings are not preventing alert creation

A correctly matched rule configured as informational may legitimately produce no alert output.

Step 4: Validate Rule Hierarchy

Many custom rules rely on inheritance.

Carefully inspect:

  • if_sid
  • if_group
  • parent rules
  • child rules
  • dependency chains

Confirm that each prerequisite rule executes successfully before expecting downstream alerts.

Broken inheritance is one of the most common causes of missing alerts fields.

Step 5: Verify Custom Rule Loading

Next, confirm that Wazuh actually loaded your custom rule file.

Review manager startup logs for:

  • successful rule loading
  • XML parsing errors
  • duplicate IDs
  • skipped files
  • configuration warnings

If the rule file never loads, wazuh-logtest cannot evaluate its contents regardless of how well the rule is written.

Step 6: Validate XML Configuration

Even small XML mistakes can prevent rules from functioning correctly.

Inspect your configuration for:

  • malformed XML
  • duplicate rule IDs
  • duplicate decoder fields
  • invalid nesting
  • missing closing tags

XML validation should always be performed before testing detection logic.

Step 7: Compare with Production Logs

Finally, compare your test log with the actual log received in production.

Verify that both contain identical:

  • formatting
  • timestamps
  • delimiters
  • field ordering
  • prefixes
  • metadata

Testing sanitized or manually edited logs often produces different results than testing raw production events.

Capturing an authentic log sample from the monitored endpoint is the most reliable way to reproduce and resolve missing alert issues.


Example: Decoder Matches but No Alert Is Generated

One of the most common wazuh-logtest scenarios is where the decoder successfully parses a log entry, but no alert appears in the JSON output.

This typically indicates that the decoding stage completed successfully while rule evaluation failed.

Let’s walk through a practical example.

Sample Log

Suppose you’re testing the following authentication log:

Jul 15 09:42:17 web01 sshd[2153]: Failed password for invalid user admin from 192.168.1.100 port 53324 ssh2

Running the log through wazuh-logtest shows that it is decoded correctly.

Decoder Example

A simplified decoder might look like this:

<decoder name="custom-sshd">
  <prematch>sshd</prematch>
  <regex>Failed password for invalid user (\S+) from (\S+)</regex>
  <order>username,srcip</order>
</decoder>

The decoder successfully extracts:

  • username = admin
  • srcip = 192.168.1.100

At this point, decoding has completed successfully.

Rule Example

Now consider the following custom rule:

<rule id="100500" level="10">
    <decoded_as>custom-sshd</decoded_as>
    <field name="action">failed</field>
    <description>Failed SSH login</description>
</rule>

Although the decoder worked, the rule never matches.

Why?

The decoder never extracted an action field.

The rule depends on:

<field name="action">failed</field>

Since that field does not exist, the condition evaluates to false.

Why the Alert Is Missing

The processing pipeline looks like this:

Raw Log
    │
    ▼
Decoder ✓
    │
Extract username ✓
Extract srcip ✓
    │
    ▼
Rule Evaluation
    │
Missing action field ✗
    │
    ▼
No Rule Match
    │
    ▼
No alerts object

Notice that nothing is technically broken.

The decoder works exactly as designed.

The rule simply requires information that is never extracted.

Corrected Configuration

There are two possible fixes.

Option 1: Modify the decoder

Extract the missing field.

<decoder name="custom-sshd">
  <prematch>sshd</prematch>
  <regex>Failed password for invalid user (\S+) from (\S+)</regex>
  <order>action,username,srcip</order>
</decoder>

Or adjust the regex so the first capture group extracts the action value.

Option 2: Modify the rule

If the action field isn’t necessary, simplify the rule.

<rule id="100500" level="10">
    <decoded_as>custom-sshd</decoded_as>
    <description>Failed SSH login</description>
</rule>

The corrected rule now evaluates successfully and generates an alert.


Example: Rule Level Prevents Alert Creation

Another common source of confusion is when a rule matches successfully but still produces no alert because of its configured severity level.

Demonstrate a Level 0 Rule

Consider the following rule:

<rule id="100510" level="0">
    <decoded_as>custom-sshd</decoded_as>
    <description>SSH authentication event</description>
</rule>

During testing:

  • Decoder matches ✓
  • Rule matches ✓
  • Alert generated ✗

The missing alert is expected because the rule is configured with level="0".

Level 0 rules are intended for classification, preprocessing, or as parent rules for inheritance, not for creating alerts.

Show Corrected Rule Level

Updating the rule to an alerting severity resolves the issue.

<rule id="100510" level="8">
    <decoded_as>custom-sshd</decoded_as>
    <description>SSH authentication failure</description>
</rule>

Now the same log produces an alert object in the JSON output.

Compare JSON Outputs

Level 0 Rule

{
  "decoder": {
    "name": "custom-sshd"
  },
  "data": {
    "username": "admin",
    "srcip": "192.168.1.100"
  }
}

Notice there is no alerts object.

Level 8 Rule

{
  "decoder": {
    "name": "custom-sshd"
  },
  "data": {
    "username": "admin",
    "srcip": "192.168.1.100"
  },
  "alerts": [
    {
      "rule": {
        "id": 100510,
        "level": 8,
        "description": "SSH authentication failure"
      }
    }
  ]
}

The only configuration change was the rule level, yet the JSON output now includes the expected alert information.


Example: Missing Required Decoder Fields

Another frequent cause of missing alerts is when the decoder only extracts part of the information required by downstream rules.

Even though the decoder matches successfully, incomplete field extraction prevents rule conditions from evaluating to true.

Broken Decoder Example

Suppose the incoming log contains:

User admin logged in from 192.168.1.100

The decoder is written as:

<decoder name="custom-login">
    <regex>User (\S+) logged in from (\S+)</regex>
    <order>username</order>
</decoder>

Although the regex captures two values, only one is assigned.

Missing Extracted Field

The decoder extracts:

username = admin

However, the second captured value is discarded because the <order> element only contains one field.

As a result:

srcip = missing

A downstream rule such as:

<field name="srcip">192\.168\..*</field>

can never match because srcip does not exist.

Correct Decoder Configuration

The decoder should assign every captured group.

<decoder name="custom-login">
    <regex>User (\S+) logged in from (\S+)</regex>
    <order>username,srcip</order>
</decoder>

Now Wazuh extracts:

  • username = admin
  • srcip = 192.168.1.100

The dependent rule has access to all required fields and can evaluate successfully.

Successful JSON Output

After correcting the decoder, wazuh-logtest produces output similar to:

{
  "decoder": {
    "name": "custom-login"
  },
  "data": {
    "username": "admin",
    "srcip": "192.168.1.100"
  },
  "alerts": [
    {
      "rule": {
        "id": 100520,
        "level": 7,
        "description": "User login detected"
      }
    }
  ]
}

This illustrates the complete processing pipeline:

  1. The decoder matches the log.
  2. All required fields are extracted.
  3. The rule conditions evaluate successfully.
  4. Wazuh generates an alert.
  5. The alerts object appears in the JSON output.

Wazuh Decoder Syntax Documentation: https://documentation.wazuh.com/current/user-manual/ruleset/ruleset-xml-syntax/decoders.html


Useful Commands for Troubleshooting

When the alerts field is missing from wazuh-logtest output, a handful of commands can quickly help you determine whether the issue lies with your decoder, rules, configuration files, or the Wazuh manager itself.

Running these commands in a logical order can significantly reduce troubleshooting time.

Running wazuh-logtest Interactively

The easiest way to test detection logic is to launch wazuh-logtest in interactive mode.

/var/ossec/bin/wazuh-logtest

After starting the tool, paste a raw log entry when prompted.

For every test, review:

  • Selected decoder
  • Extracted fields
  • Matching rule IDs
  • Rule levels
  • Final alert output

Testing interactively allows you to make incremental changes to decoders or rules and immediately verify the results.

Wazuh Log Testing Documentation: https://documentation.wazuh.com/current/user-manual/ruleset/testing.html

Testing Individual Rules

If a specific rule is expected to generate an alert, isolate it during testing.

Verify:

  • The correct decoder is selected.
  • Every required field is present.
  • Regex conditions evaluate successfully.
  • if_sid and if_group dependencies are satisfied.
  • The rule’s level is greater than zero.

Testing one rule at a time makes it much easier to identify which condition is preventing a match.

Validating XML Files

Before assuming there is a logic problem, verify that your XML files are valid.

Check for:

  • Missing closing tags
  • Invalid nesting
  • Duplicate rule IDs
  • Duplicate decoder fields
  • Incorrect <order> entries
  • Improperly escaped characters

Many “missing alert” issues are ultimately caused by XML syntax errors that prevent custom rules or decoders from loading.

Checking Wazuh Manager Logs

If custom rules appear to be ignored, inspect the Wazuh manager logs during startup.

Typical log locations include:

/var/ossec/logs/ossec.log

Look for messages indicating:

  • XML parsing errors
  • Failed rule loading
  • Duplicate IDs
  • Invalid decoder definitions
  • Configuration warnings

These logs often reveal configuration problems that are not immediately visible in wazuh-logtest.

Restarting the Manager After Changes

Whenever you modify:

  • decoders
  • rules
  • ossec.conf
  • included XML files

restart the Wazuh manager so the changes are reloaded.

For systems using systemd:

sudo systemctl restart wazuh-manager

After the restart:

  1. Confirm there are no startup errors.
  2. Verify your custom rules loaded successfully.
  3. Run wazuh-logtest again with the same sample log.

Skipping this step is a common reason administrators believe their configuration changes are being ignored.


Best Practices for Reliable wazuh-logtest Results

Following a few proven practices when developing decoders and rules can help you avoid many of the issues that cause the alerts field to be missing from JSON output.

Design Decoders Before Rules

Always create and validate your decoder before writing rules that depend on it.

First confirm that the decoder:

  • Matches the correct log format.
  • Extracts all required fields.
  • Produces consistent output for different log samples.

Only then should you build rules around those extracted fields.

Keep Rule IDs Unique

Every custom rule should have a unique rule ID.

Duplicate IDs can lead to:

  • Rules being overridden
  • Unexpected matches
  • Inconsistent testing results
  • Difficult-to-diagnose behavior

Reserve a dedicated ID range for custom rules to minimize conflicts with the built-in ruleset.

Use Meaningful Rule Levels

Choose alert levels that reflect the severity of the event.

For example:

  • Level 0: Classification or parent rules only
  • Levels 1–5: Informational or low-priority events
  • Levels 6–10: Medium- to high-priority security events
  • Levels 11+: Critical detections requiring immediate attention

Using appropriate rule levels makes testing more predictable and helps downstream integrations prioritize alerts correctly.

Test with Real Production Logs

Whenever possible, test using raw logs captured from production systems.

Avoid manually rewriting or simplifying log entries, as even small differences in:

  • spacing
  • timestamps
  • delimiters
  • metadata
  • field order

can affect decoder matching and rule evaluation.

Testing with authentic data provides the most accurate representation of production behavior.

Validate XML Before Deployment

Treat XML validation as a required step before deploying any configuration changes.

Verify that:

  • XML is well-formed.
  • Rule IDs are unique.
  • Decoder definitions are complete.
  • <order> entries match regex capture groups.
  • Include statements reference the correct files.

Catching syntax issues early prevents unnecessary troubleshooting later.

Organize Custom Rules Separately

Store custom decoders and rules in dedicated files rather than modifying the default Wazuh ruleset.

This approach offers several benefits:

  • Easier upgrades
  • Simpler backups
  • Cleaner troubleshooting
  • Reduced risk of overwriting customizations during updates

Document Rule Dependencies

Many custom rules depend on parent rules, decoder fields, or group membership.

Document:

  • Parent rule IDs
  • if_sid relationships
  • if_group dependencies
  • Required extracted fields
  • Expected decoder names

Maintaining clear documentation makes future troubleshooting much easier, especially in larger deployments.

Test Incrementally After Every Change

Avoid making multiple configuration changes before testing.

Instead:

  1. Modify one decoder or rule.
  2. Restart the Wazuh manager.
  3. Run wazuh-logtest.
  4. Review the results.
  5. Repeat for the next change.

Incremental testing makes it much easier to pinpoint the exact change that introduced an issue.


Frequently Asked Questions (FAQ)

Question: Why is the alerts field missing in wazuh-logtest JSON output?

The alerts field is usually missing because no rule generated an alert.

Common causes include missing rule matches, rule levels set to 0, unsatisfied rule conditions, missing decoder fields, or custom rules that failed to load.

Question: Can a decoder work without generating an alert?

Yes. A decoder’s responsibility is to parse logs and extract structured fields.

Alert generation only occurs if one or more rules successfully evaluate those fields and produce an alert.

Question: Does a level 0 rule create alerts?

No. Rules configured with level="0" are intended for classification, preprocessing, or serving as parent rules.

They typically do not generate alert objects in wazuh-logtest output.

Question: How do I know whether my decoder matched successfully?

Review the wazuh-logtest output for:

  • Decoder name
  • Extracted fields
  • Captured values

If the expected decoder appears and the required fields are populated, the decoder matched successfully.

Question: Why are my custom rules not triggering?

Common reasons include:

  • Required fields were not extracted.
  • Rule conditions are incorrect.
  • if_sid or if_group dependencies are not satisfied.
  • The rule level is set to 0.
  • The custom rule file failed to load because of XML errors or configuration issues.

Question: Do parent rules affect child rule execution?

Yes. Child rules that use directives such as if_sid depend on their parent rules matching first.

If the parent rule does not execute, the child rule will not be evaluated.

Question: Can malformed XML prevent rules from loading?

Absolutely. Invalid XML can prevent an entire decoder or rule file from loading.

Always validate your XML and review the Wazuh manager logs after making configuration changes.

Question: Should I restart the Wazuh manager after editing rules?

Yes. Changes to rules, decoders, or related configuration files are not applied until the Wazuh manager reloads them.

Restart the manager and verify there are no startup errors before testing again.

Question: Does wazuh-logtest behave exactly like production event processing?

For decoder and rule evaluation, wazuh-logtest uses the same analysis engine as the Wazuh manager, making it highly representative of production behavior.

However, certain features that rely on live event streams, such as long-term event correlation, frequency thresholds over time, or distributed cluster behavior, may not be fully replicated in isolated tests.

Question: How can I verify that my custom rules have been loaded?

After restarting the Wazuh manager:

  1. Review /var/ossec/logs/ossec.log for startup messages.
  2. Check for XML parsing errors or duplicate rule IDs.
  3. Run wazuh-logtest and confirm that your custom rule ID appears when the expected conditions are met.

Conclusion

When the alerts field is missing from wazuh-logtest JSON output, the root cause is almost always found within the event processing pipeline rather than the tool itself.

The most common reasons include missing rule matches, rules configured with level="0", unsatisfied rule conditions, incomplete decoder field extraction, parent rule dependency failures, malformed XML, or custom rules that were never loaded.

A successful decoder match is only the first step.

Before troubleshooting rule logic, verify that your decoder extracted every field required by downstream rules.

Missing or incorrectly parsed fields are one of the most frequent reasons alerts fail to appear.

From there, systematically examine rule conditions, alert levels, inheritance chains, XML configuration, and manager startup logs.

Working through each stage of the pipeline methodically is far more effective than making multiple configuration changes at once.

By following Wazuh best practices, such as validating decoders before writing rules, keeping custom rules organized, using unique rule IDs, testing with real production logs, and validating XML before deployment, you can ensure that wazuh-logtest produces reliable, predictable results and accurately reflects how your detection logic will behave in production.

Related Guides:

Be First to Comment

    Leave a Reply

    Your email address will not be published. Required fields are marked *