Modern infrastructure rarely generates simple, flat log entries anymore.
Cloud platforms, container orchestration systems, SaaS applications, and security tools typically produce deeply structured JSON logs containing nested objects, arrays, and complex metadata.
While this structure makes logs easier for applications to process programmatically, it also introduces new challenges for security analysts who need to search, correlate, and create detection rules.
Fortunately, Wazuh includes a built-in JSON decoder that can automatically parse JSON-formatted logs without requiring custom decoders in many situations.
This significantly reduces the effort required to onboard structured log sources such as AWS CloudTrail, Kubernetes, Docker, Microsoft Azure, GitHub Audit Logs, and numerous other cloud services.
However, automatic parsing does not always behave exactly as users expect.
How Are Nested JSON Objects Flattened?
Nested JSON objects are typically flattened into dot-separated field names, while arrays may be represented differently depending on their contents.
These transformations can make writing rules, creating decoders, and troubleshooting field extraction more difficult, especially for administrators who are unfamiliar with how Wazuh internally processes JSON data.
For example, a JSON object like:
{
"user": {
"name": "alice",
"department": "security"
}
}may become fields such as:
user.name = alice
user.department = securityLikewise, arrays containing multiple values or nested objects often require special handling before they can be reliably matched in Wazuh rules.
Understanding these behaviors is essential if you plan to monitor cloud infrastructure, Kubernetes clusters, container workloads, or modern APIs that rely heavily on nested JSON payloads.
In this guide, you’ll learn how Wazuh parses JSON logs, why nested objects are flattened, how arrays are represented, and the best techniques for writing reliable detection rules that work with complex JSON structures.
You’ll also learn common troubleshooting techniques for handling nested keys and arrays when the default parsing behavior isn’t sufficient.
Related Guides:
- How to Create Custom Detection Rules in Wazuh (With Examples)
- Custom Decoder Isn’t Matching: Wazuh Logtest Deep Dive
How Wazuh Parses JSON Logs
Built-in JSON Decoder
One of Wazuh’s most useful features is its built-in JSON decoder.
Unlike traditional syslog messages that require custom regular expressions, JSON logs can often be parsed automatically with little or no configuration.
When Wazuh receives a valid JSON payload, the JSON decoder recursively examines the document, extracts fields, and stores them as dynamic fields that rules can later reference.
This makes integrating cloud-native services significantly easier since many platforms already emit JSON by default.
Examples include:
- AWS CloudTrail
- AWS GuardDuty
- Kubernetes Audit Logs
- Docker
- Microsoft Azure Activity Logs
- GitHub Audit Logs
- Elastic Beats
- Numerous SIEM and observability products
Because the decoder understands JSON structure, administrators rarely need to create complex XML decoders for standard log formats.
For details on the decoder’s capabilities, the official Wazuh documentation provides an overview of supported JSON parsing behavior.
Automatic Field Extraction
Once Wazuh recognizes a log as valid JSON, it automatically extracts every supported key-value pair.
For example:
{
"hostname": "web01",
"severity": "warning",
"process": "nginx",
"status": 403
}becomes internally accessible as:
hostname = web01
severity = warning
process = nginx
status = 403These extracted fields can then be referenced directly inside custom rules using the <field> element.
For example:
<field name="severity">warning</field>No regular expressions are needed because the JSON decoder has already parsed the structure.
This automatic extraction greatly simplifies rule creation compared to parsing plain text logs.
Related Guide: How to Test Wazuh Rules
Dynamic Fields vs Static Fields
Wazuh distinguishes between two different types of extracted data:
Static Fields
Static fields are predefined fields that Wazuh recognizes across multiple log formats.
Examples include:
- srcip
- dstip
- user
- program_name
- location
- hostname
These fields are standardized and commonly referenced throughout the default ruleset.
Dynamic Fields
Dynamic fields are created directly from the JSON document.
For example:
{
"cloud": {
"provider": "aws"
},
"event": {
"action": "CreateUser"
}
}becomes:
cloud.provider
event.actionDynamic fields preserve much more contextual information, making them particularly useful for cloud security monitoring.
JSON documents frequently contain multiple layers of nested objects.
Example:
{
"user": {
"identity": {
"name": "alice",
"department": "SOC"
}
}
}Rather than storing nested objects internally, Wazuh flattens the hierarchy into individual field names:
user.identity.name = alice
user.identity.department = SOCFlattening allows the rule engine to search each value independently without recursively traversing JSON objects during rule evaluation.
Although this representation may initially seem unusual, it improves performance and makes field matching much simpler.
How Arrays Are Represented
Arrays require slightly different handling than nested objects.
Simple arrays such as:
{
"roles": [
"admin",
"developer",
"security"
]
}may be stored as multiple values associated with the same logical field or represented according to Wazuh’s internal parsing behavior.
Arrays containing nested objects introduce additional complexity.
Example:
{
"resources": [
{
"type": "EC2",
"id": "i-12345"
},
{
"type": "S3",
"id": "bucket01"
}
]
}Because multiple objects share the same parent key, creating detection rules often requires understanding exactly how Wazuh indexed each element.
Later in this guide, you’ll learn techniques for reliably parsing these nested arrays and matching individual values.
Example of a Simple JSON Log
Consider the following log:
{
"timestamp": "2026-07-15T16:05:32Z",
"host": {
"name": "web01",
"ip": "192.168.10.20"
},
"event": {
"action": "login",
"status": "success"
}
}After parsing, Wazuh exposes fields similar to:
timestamp
host.name
host.ip
event.action
event.statusThese flattened fields can immediately be referenced inside custom rules without creating additional decoders.
This automatic transformation is one of the reasons Wazuh integrates so well with modern JSON-based logging systems.
Understanding Flattened Nested Keys in Wazuh
What Are Flattened Keys?
Flattened keys are the field names that Wazuh generates after parsing nested JSON objects.
Instead of preserving the original hierarchical structure, Wazuh combines each parent and child key into a single dot-separated field name.
For example:
{
"user": {
"identity": {
"username": "alice"
}
}
}becomes:
user.identity.usernameFrom the perspective of the rule engine, this behaves just like any other searchable field.
Why Wazuh Flattens Nested JSON Objects
Flattening provides several important advantages.
Rather than recursively searching through deeply nested JSON trees during every rule evaluation, Wazuh converts each nested value into an individual searchable field.
This approach offers benefits such as:
- Faster rule evaluation
- Simpler field matching
- Lower parsing overhead
- Consistent field references
- Easier integration with OpenSearch indexing
Many logging and analytics platforms, including Elasticsearch and OpenSearch, use similar approaches when indexing structured JSON documents because flattened fields are significantly easier to search efficiently.
Dot Notation Explained
Dot notation simply joins parent and child object names using periods.
Consider this JSON:
{
"request": {
"client": {
"ip": "10.0.0.25"
}
}
}After parsing:
request.client.ipEach period represents another level of nesting within the original JSON document.
When writing Wazuh rules, administrators reference this complete flattened field name.
Example:
<field name="request.client.ip">10.0.0.25</field>Understanding dot notation is one of the most important skills for building reliable JSON-based detection rules.
Common Examples from Cloud Logs
Many of today’s most common log sources produce deeply nested JSON. Understanding how these logs are flattened makes troubleshooting much easier.
AWS CloudTrail
CloudTrail records often contain nested user identity information.
Example:
"userIdentity": {
"type": "IAMUser",
"userName": "alice"
}becomes:
userIdentity.type
userIdentity.userNameThese fields are frequently used to detect unauthorized API activity or privilege changes.
Related Guide: How to Monitor AWS CloudTrail Logs Using Wazuh
Microsoft Azure
Azure Activity Logs commonly contain nested authorization and caller information.
Example:
authorization.action
authorization.scope
claims.name
claims.appidFlattened fields make it easier to write rules that detect administrative actions, permission changes, or failed authentication events.
Kubernetes
Kubernetes audit logs are among the most deeply nested JSON sources.
Typical flattened fields include:
objectRef.resource
objectRef.namespace
user.username
sourceIPs
verb
requestURIThese fields are commonly used to detect suspicious API activity, unauthorized namespace access, and privilege escalation attempts.
Related Guide: How to Monitor Kubernetes Using Wazuh
Docker
Docker logs often include nested container metadata.
Examples include:
container.id
container.name
container.image
container.labels.environmentThese fields enable administrators to create highly specific detection rules for individual containers or workloads.
GitHub Audit Logs
GitHub enterprise audit events contain nested actor, repository, organization, and workflow information.
Common flattened fields include:
actor.login
repository.name
organization.name
actionThese fields are useful for detecting suspicious repository access, administrative changes, or authentication events within GitHub environments.
Understanding Nested Arrays in JSON Logs
What Is a Nested Array?
A nested array is a JSON array that contains multiple values under a single key.
Those values may be simple strings, numbers, booleans, or even entire JSON objects. Arrays allow applications to represent multiple related items without repeating the parent field.
For example:
{
"roles": [
"admin",
"developer",
"auditor"
]
}In this example, the roles field contains three values instead of a single string.
Modern cloud platforms make extensive use of arrays because users, permissions, resources, network interfaces, API requests, and configuration settings frequently involve multiple related objects.
While JSON arrays are easy for applications to process, they introduce additional complexity for log analysis platforms because each element must be interpreted correctly during parsing.
Arrays of Strings
The simplest type of array contains only primitive values such as strings.
Example:
{
"sourceIPs": [
"192.168.1.10",
"10.0.0.25",
"172.16.0.8"
]
}Here, every element is simply a string.
These arrays are common in:
- Kubernetes audit logs
- Firewall logs
- CloudTrail source IP tracking
- Network monitoring platforms
- Access control lists
Since every element shares the same data type, these arrays are relatively straightforward for Wazuh to process.
Arrays of Objects
Arrays become significantly more complex when each element is its own JSON object.
Example:
{
"instances": [
{
"id": "i-01a23b",
"state": "running"
},
{
"id": "i-98f76c",
"state": "stopped"
}
]
}Instead of containing simple values, every array element has its own nested fields.
This creates multiple levels of hierarchy that Wazuh must flatten before individual values become searchable.
Arrays of objects are extremely common in cloud APIs because a single event often affects multiple resources simultaneously.
Examples include:
- Multiple EC2 instances
- Several Kubernetes containers
- Azure virtual machines
- Docker containers
- IAM policy statements
- Security group rules
These arrays typically require more careful rule design than arrays containing simple strings.
Mixed Arrays
Although less common, JSON arrays can contain different data types within the same array.
Example:
{
"values": [
"administrator",
15,
true,
{
"department": "security"
}
]
}This is known as a mixed array.
While valid JSON, mixed arrays are generally discouraged because they make parsing more complicated and reduce consistency across applications.
Most cloud providers avoid this design, but custom applications and internally developed APIs sometimes produce mixed arrays.
When mixed arrays appear in logs, it’s important to verify exactly how Wazuh parses each element before creating detection rules.
Why Arrays Are More Difficult to Parse
Nested objects have a predictable structure because each child belongs to a named parent key.
Arrays are different.
Every element occupies a position rather than a unique field name, and arrays may contain:
- Zero elements
- One element
- Hundreds of elements
- Different object structures
- Duplicate values
Because of this variability, Wazuh cannot always expose array contents as neatly as flattened objects.
Some arrays are expanded into searchable dynamic fields, while others require additional processing depending on their structure.
Arrays of nested objects are especially challenging because multiple child objects may contain identical field names.
For example:
{
"users": [
{
"name": "Alice"
},
{
"name": "Bob"
}
]
}Both objects contain a name field, making it necessary for Wazuh to distinguish between multiple instances of the same key.
Understanding how these arrays are parsed is essential when troubleshooting why a rule fails to match expected values.
Common Real-World Examples
Nested arrays appear in nearly every modern cloud platform.
Some of the most common examples include:
| Platform | Typical Nested Arrays |
|---|---|
| AWS CloudTrail | Resources, policy statements, request parameters |
| Microsoft Azure | Authorization scopes, role assignments, affected resources |
| Kubernetes | Containers, source IPs, admission controllers, groups |
| Docker | Labels, mounted volumes, exposed ports, environment variables |
| GitHub Audit Logs | Repository collaborators, team memberships, permission changes |
| Microsoft 365 | Modified properties, recipients, attachments |
| Google Cloud | IAM bindings, service accounts, firewall rules |
Learning to recognize these structures makes it much easier to build accurate Wazuh rules.
Related Guides:
Understanding Example JSON Logs with Nested Objects and Arrays
Simple Nested Object Example
Consider the following JSON log:
{
"host": {
"hostname": "server01",
"ip": "192.168.1.20"
},
"event": {
"action": "login"
}
}This log contains two nested objects: host and event.
After parsing, Wazuh generates flattened fields similar to:
host.hostname
host.ip
event.actionThese flattened field names can be referenced directly inside custom rules using the <field> element.
Deeply Nested JSON Example
Cloud services often generate logs with multiple layers of nesting.
Example:
{
"request": {
"user": {
"identity": {
"username": "alice",
"department": "SOC"
}
}
}
}Rather than preserving this hierarchy internally, Wazuh extracts fields such as:
request.user.identity.username
request.user.identity.departmentRegardless of how deeply the object is nested, each level becomes part of the final field name using dot notation.
JSON with Nested Arrays
Now consider a log that combines nested objects with arrays.
{
"event": {
"action": "CreateUser"
},
"affectedUsers": [
{
"username": "alice",
"role": "Admin"
},
{
"username": "bob",
"role": "Developer"
}
]
}This structure is considerably more complicated than a simple nested object because the affectedUsers field contains multiple JSON objects.
Depending on the array structure and Wazuh’s parsing behavior, individual values may not always appear exactly as expected during rule testing.
This is why examining parsed output with tools such as wazuh-logtest is an important step before writing detection rules.
Related Guide: Custom Decoder Isn’t Matching: Wazuh Logtest Deep Dive
Complex Cloud Audit Log Example
The following simplified CloudTrail event demonstrates how quickly JSON structures can grow.
{
"eventName": "RunInstances",
"userIdentity": {
"type": "IAMUser",
"userName": "alice"
},
"resources": [
{
"type": "AWS::EC2::Instance",
"ARN": "arn:aws:ec2:..."
}
],
"sourceIPAddress": "198.51.100.10",
"requestParameters": {
"instanceType": "t3.medium",
"securityGroupIds": [
"sg-123456",
"sg-654321"
]
}
}This single log contains:
- Nested objects
- Arrays of objects
- Arrays of strings
- Multiple hierarchy levels
Cloud audit logs from Azure, Kubernetes, GitHub, and Google Cloud often have a similar level of complexity.
What Wazuh Actually Extracts
Although the original JSON may contain deeply nested structures, Wazuh ultimately exposes a collection of searchable fields.
For the previous example, extracted fields may resemble:
eventName
userIdentity.type
userIdentity.userName
resources.type
resources.ARN
sourceIPAddress
requestParameters.instanceType
requestParameters.securityGroupIdsNotice that the nested hierarchy has been flattened into individual field names.
This transformation allows the Wazuh rules engine to search fields directly without traversing the original JSON structure.
Before creating production rules, it’s always a good practice to inspect the parsed output to confirm the exact field names generated from your logs.
How Wazuh Flattens Nested JSON Fields
Object Flattening Process
When Wazuh receives a valid JSON log, the built-in JSON decoder recursively walks through each object in the document.
Each nested key is combined with its parent keys to create a unique, searchable field name.
For example:
{
"cloud": {
"account": {
"id": "123456789012"
}
}
}becomes:
cloud.account.idThis process continues until every supported value has been extracted.
Flattening removes the need for the rules engine to repeatedly navigate complex JSON trees during event analysis.
Generated Field Names
Every flattened field preserves its full path within the original JSON document.
For example:
{
"kubernetes": {
"pod": {
"name": "frontend",
"namespace": "production"
}
}
}Produces fields similar to:
kubernetes.pod.name
kubernetes.pod.namespaceThe resulting names are intuitive because they mirror the original JSON hierarchy.
This consistency makes it much easier to identify which part of the original log produced a particular field.
Maximum Depth Considerations
Most production JSON documents are only a few levels deep, but some cloud platforms generate exceptionally complex structures.
Examples include:
- AWS IAM policies
- Kubernetes admission controller logs
- Azure Resource Manager events
- GitHub enterprise audit logs
Although Wazuh can process deeply nested JSON, excessive nesting increases parsing complexity and can make rule creation more difficult.
As nesting levels grow, field names become longer and easier to mistype, so verifying the extracted field names before writing rules is always recommended.
Dynamic Field Creation
Unlike predefined static fields such as srcip or user, flattened JSON fields are created dynamically from the incoming log.
For example:
{
"application": {
"version": "5.8.2",
"environment": "production"
}
}creates dynamic fields such as:
application.version
application.environmentBecause dynamic fields are generated automatically, Wazuh can adapt to virtually any JSON schema without requiring custom XML decoders for every log source.
This flexibility is one of the primary reasons Wazuh integrates effectively with modern cloud-native platforms and APIs.
How This Affects Rule Writing
Understanding flattened field names is essential when writing custom Wazuh rules.
A rule must reference the exact field name generated by the JSON decoder. Even a small difference in capitalization, nesting level, or spelling can prevent the rule from matching.
For example:
<field name="userIdentity.userName">alice</field>will only work if userIdentity.userName matches the extracted field exactly.
Before creating or troubleshooting custom rules, inspect the parsed event using wazuh-logtest to verify the generated field names.
This helps eliminate guesswork and reduces false negatives caused by incorrect field references.
Related Guides:
- How to Create Custom Detection Rules in Wazuh (With Examples)
- How to Test Wazuh Rules
- Troubleshooting wazuh-logtest: Why Alerts Are Missing from JSON Output
Example JSON Logs with Nested Objects and Arrays
Understanding how Wazuh parses nested JSON becomes much easier when you compare the original log with the fields that Wazuh ultimately extracts.
The following examples demonstrate increasingly complex JSON structures that are commonly encountered in cloud environments.
Simple Nested Object Example
The following log contains two nested objects: user and event.
{
"user": {
"name": "alice",
"department": "Security"
},
"event": {
"action": "login",
"status": "success"
}
}Although the JSON contains multiple levels, Wazuh flattens each nested key into a searchable field.
Resulting fields:
user.name = alice
user.department = Security
event.action = login
event.status = successEach field can now be referenced directly in custom rules without needing to traverse the original JSON hierarchy.
Deeply Nested JSON Example
Cloud platforms frequently produce logs that contain several layers of nested objects.
Example:
{
"request": {
"user": {
"identity": {
"username": "alice",
"groups": {
"primary": "SOC",
"secondary": "CloudOps"
}
}
}
}
}Wazuh recursively parses every object and generates flattened field names similar to:
request.user.identity.username
request.user.identity.groups.primary
request.user.identity.groups.secondaryNotice that every level of nesting becomes part of the field name.
This process is known as dot notation, and it preserves the hierarchy while making each value individually searchable.
JSON with Nested Arrays
Nested arrays are considerably more complex because each array can contain multiple elements.
Example:
{
"event": {
"action": "CreateUser"
},
"users": [
{
"username": "alice",
"role": "Administrator"
},
{
"username": "bob",
"role": "Developer"
}
]
}Unlike simple objects, arrays may contain multiple objects with identical keys.
In this example:
- Every object contains a
username - Every object contains a
role - Both objects belong to the same parent array
Understanding exactly how these values are extracted is essential before writing detection rules.
This is one reason why testing logs with wazuh-logtest is highly recommended.
Complex Cloud Audit Log Example
Modern cloud audit logs often combine nested objects, nested arrays, metadata, and request parameters into a single event.
Example:
{
"eventName": "CreatePolicy",
"userIdentity": {
"type": "IAMUser",
"userName": "alice"
},
"requestParameters": {
"policyName": "SecurityAdmins",
"statements": [
{
"effect": "Allow",
"action": [
"ec2:*",
"iam:*"
]
}
]
},
"sourceIPAddress": "198.51.100.25"
}Within this single log you can see:
- Nested objects
- Arrays of objects
- Arrays of strings
- Multiple hierarchy levels
- Various data types
CloudTrail, Azure Activity Logs, Kubernetes Audit Logs, Microsoft 365, and GitHub Audit Logs all generate similarly structured JSON events.
What Wazuh Actually Extracts
Although the original JSON appears highly structured, Wazuh converts it into individual searchable fields.
For the previous example, extracted fields might resemble:
eventName
userIdentity.type
userIdentity.userName
requestParameters.policyName
requestParameters.statements.effect
requestParameters.statements.action
sourceIPAddressThese flattened fields become the values that Wazuh rules reference during event evaluation.
Whenever you’re unsure how a particular JSON document was parsed, inspect the parsed output rather than relying on the original JSON structure.
The official Wazuh documentation also recommends validating parsed fields during rule development to ensure that field names match your expectations.
How Wazuh Flattens Nested JSON Fields
Object Flattening Process
When Wazuh receives a valid JSON log, its built-in JSON decoder recursively walks through every object in the document.
Each nested object is broken down into individual key-value pairs while preserving the original hierarchy through dot notation.
For example:
{
"cloud": {
"provider": "AWS",
"region": "us-east-1"
}
}becomes:
cloud.provider
cloud.regionThis recursive flattening continues until every supported value has been extracted.
Flattening greatly improves search performance because Wazuh can evaluate individual fields directly instead of repeatedly traversing nested JSON trees.
Generated Field Names
The generated field names reflect the exact path taken through the original JSON document.
For example:
{
"kubernetes": {
"pod": {
"namespace": "production",
"name": "frontend-api"
}
}
}produces fields such as:
kubernetes.pod.namespace
kubernetes.pod.nameBecause the hierarchy is preserved, administrators can usually identify the source location of each field simply by reading its name.
This predictable naming convention also makes rule maintenance much easier.
Maximum Depth Considerations
Most JSON logs contain only a few nested levels.
However, cloud providers frequently generate much deeper structures.
Examples include:
- AWS IAM policies
- Kubernetes admission controller events
- Azure Resource Manager logs
- GitHub enterprise audit events
While Wazuh supports deeply nested JSON, extremely deep objects create:
- Longer field names
- More complicated rule conditions
- Harder troubleshooting
- Greater potential for typing mistakes
If you find yourself referencing exceptionally long field names, verify them carefully using parsed output rather than copying directly from the original JSON.
Dynamic Field Creation
One of Wazuh’s strengths is that it creates fields dynamically.
Unlike traditional log parsing, you do not need to define every possible field beforehand.
For example:
{
"application": {
"version": "4.8.0",
"environment": "production",
"cluster": "east"
}
}automatically produces:
application.version
application.environment
application.clusterThis allows Wazuh to support virtually any JSON schema without requiring custom decoders for every application.
How This Affects Rule Writing
Flattened fields directly determine how your custom rules must be written.
Suppose Wazuh extracts:
userIdentity.userNameYour rule must reference that exact field.
For example:
<field name="userIdentity.userName">alice</field>Using:
<field name="username">alice</field>would fail because no such field exists.
For this reason, experienced Wazuh users recommend validating parsed fields before writing rules instead of assuming field names from the original JSON.
Related Guide: How to Create Custom Detection Rules in Wazuh (With Examples)
Working with Flattened Nested Keys in Wazuh Rules
Referencing Dot-Notation Fields
Once JSON fields have been flattened, they can be referenced directly inside a Wazuh rule using the <field> element.
For example, given the parsed field:
user.identity.departmentyour rule can match it like this:
<field name="user.identity.department">Security</field>The field name must exactly match the name generated by the JSON decoder, including capitalization and every level of nesting.
Even a single missing parent object will prevent the rule from matching.
Matching Nested Values
Any flattened field can be matched using exact values or regular expressions.
For example:
<field name="event.action">DeleteUser</field>or
<field name="sourceIPAddress">^192\.168\.</field>This flexibility allows you to detect specific cloud events, privileged actions, suspicious IP ranges, or application behaviors using data extracted from nested JSON.
Using Dynamic Fields
Dynamic fields work exactly like predefined Wazuh fields once they have been extracted.
Suppose this JSON is received:
{
"container": {
"image": "nginx:latest",
"namespace": "production"
}
}You can reference the generated fields directly:
<field name="container.image">nginx:latest</field>
<field name="container.namespace">production</field>Because dynamic fields are created automatically, the same rule-writing techniques apply regardless of whether the log originated from Kubernetes, Docker, AWS, Azure, or a custom application.
Practical Rule Examples
A rule that detects AWS IAM user creation might look like:
<rule id="100500" level="8">
<decoded_as>json</decoded_as>
<field name="eventName">CreateUser</field>
<description>AWS IAM user created</description>
</rule>Likewise, detecting a Kubernetes pod deletion could use:
<field name="verb">delete</field>
<field name="objectRef.resource">pods</field>Both examples rely entirely on flattened JSON fields produced by the built-in JSON decoder.
Common Mistakes
When working with flattened JSON fields, administrators frequently encounter the same problems:
- Referencing the original JSON hierarchy instead of the flattened field name.
- Misspelling a parent key in dot notation.
- Using incorrect capitalization in field names.
- Assuming arrays are parsed as individual indexed fields.
- Creating rules before verifying how Wazuh actually parsed the log.
- Forgetting to test rules with real production events.
Security practitioners consistently recommend validating field extraction first, then writing rules based on the parsed output rather than the raw JSON.
This workflow reduces troubleshooting time and helps ensure your rules trigger reliably.
Related Guides:
Working with Flattened Nested Keys in Wazuh Rules
Once Wazuh has flattened a JSON document into dot-notation fields, those fields become available for use in custom rules.
Understanding how to reference them correctly is essential for creating reliable detections and avoiding false negatives.
Referencing Dot-Notation Fields
Flattened fields are referenced using the <field> element in a Wazuh rule. The field name must exactly match the one generated by the JSON decoder.
For example, if Wazuh extracts:
user.identity.username = aliceyour rule should reference it like this:
<field name="user.identity.username">alice</field>The field path is case-sensitive and includes every parent object from the original JSON hierarchy.
If the generated field is:
request.client.ipthen this is correct:
<field name="request.client.ip">192.168.1.100</field>Whereas this would never match:
<field name="client.ip">192.168.1.100</field>Because the parent object (request) has been omitted.
Matching Nested Values
Flattened fields support the same matching methods as other Wazuh fields.
You can perform exact matches:
<field name="event.action">DeleteUser</field>Or use regular expressions:
<field name="sourceIPAddress">^10\.0\.</field>This flexibility allows you to detect:
- Specific API operations
- Administrative actions
- Suspicious usernames
- IP address ranges
- Container names
- Kubernetes namespaces
The only difference is that the field name reflects the flattened JSON path instead of a predefined static field.
Using Dynamic Fields
Most flattened JSON fields are created dynamically at runtime.
Suppose Wazuh parses this log:
{
"application": {
"service": "payments",
"environment": "production",
"version": "5.2.1"
}
}The following dynamic fields become available:
application.service
application.environment
application.versionThese can immediately be used inside rules without creating a custom decoder.
For example:
<field name="application.environment">production</field>This dynamic field capability is one of the reasons Wazuh integrates so well with cloud-native applications, where log schemas often change over time.
Practical Rule Examples
Suppose an AWS CloudTrail log contains:
eventName = CreateUser
userIdentity.userName = aliceA simple detection rule could be:
<rule id="100500" level="8">
<decoded_as>json</decoded_as>
<field name="eventName">CreateUser</field>
<description>AWS IAM user created</description>
</rule>Another example for Kubernetes:
<rule id="100501" level="10">
<decoded_as>json</decoded_as>
<field name="verb">delete</field>
<field name="objectRef.resource">pods</field>
<description>Kubernetes pod deleted</description>
</rule>Both examples rely entirely on flattened JSON fields rather than custom regular expressions.
Common Mistakes
Several common mistakes prevent custom rules from matching flattened JSON fields correctly.
The most frequent issues include:
- Using the original JSON hierarchy instead of the flattened field name.
- Omitting one or more parent objects in dot notation.
- Incorrect capitalization of field names.
- Assuming arrays create numbered field names automatically.
- Writing rules before verifying the parsed output.
- Copying field names directly from documentation instead of the actual log.
Before writing production rules, always inspect the parsed output using wazuh-logtest to confirm the exact field names created by the JSON decoder.
Working with Nested Arrays in Wazuh
Arrays are one of the more challenging aspects of JSON parsing because they can contain multiple values or objects under the same parent key.
While Wazuh handles many array structures automatically, understanding how arrays are represented internally helps you build more accurate rules.
How Arrays Are Indexed
Unlike programming languages, Wazuh does not expose array elements using explicit numeric indexes such as:
users[0].username
users[1].usernameInstead, Wazuh processes array contents according to its JSON decoder logic and exposes searchable fields based on the extracted values.
The exact representation depends on the array’s structure and the data types it contains.
For simple arrays of primitive values, Wazuh can often make the values available without requiring positional indexing.
This behavior keeps rule writing simpler while avoiding dependencies on the order of array elements.
Matching Array Elements
Arrays of strings are generally the easiest to work with.
Consider the following JSON:
{
"groups": [
"Administrators",
"Security",
"CloudOps"
]
}Depending on how the JSON is parsed, you can create rules that match values contained within the array rather than relying on a specific position.
For example, detecting membership in the Administrators group is typically more useful than matching the first or second element of the array.
When testing array-based rules, always confirm how the array values appear in the parsed event before writing detection logic.
Handling Arrays of Objects
Arrays of objects require additional care because each element contains its own set of nested fields.
Example:
{
"resources": [
{
"type": "AWS::EC2::Instance",
"id": "i-123456"
},
{
"type": "AWS::S3::Bucket",
"id": "company-backups"
}
]
}Here, multiple objects share the same field names (type and id).
Depending on the structure of the log and Wazuh’s parsing behavior, these values may not always be represented in a way that’s easy to match individually.
If your detection logic depends on a specific object within the array, you may need to preprocess the logs before they reach Wazuh or simplify the JSON structure at the source.
When Array Parsing Becomes Limited
Although Wazuh’s JSON decoder handles many common array formats, some structures present inherent limitations.
Examples include:
- Arrays containing hundreds of objects.
- Deeply nested arrays within other arrays.
- Mixed arrays containing different data types.
- Arrays with inconsistent object schemas.
- Variable-length arrays generated by cloud APIs.
In these cases, extracting every element into easily searchable fields may not be practical or possible.
When you encounter these limitations, consider transforming the logs before ingestion using tools such as Logstash, Fluent Bit, or OpenSearch ingest pipelines.
Normalizing the data upstream often simplifies rule writing and improves detection accuracy.
Practical Examples
A Kubernetes audit log may contain an array of source IP addresses:
{
"sourceIPs": [
"10.10.1.5",
"192.168.100.15"
]
}Similarly, an AWS CloudTrail event may include multiple affected resources:
{
"resources": [
{
"ARN": "arn:aws:ec2:..."
},
{
"ARN": "arn:aws:s3:..."
}
]
}Before writing rules against these arrays, use wazuh-logtest to determine exactly how Wazuh extracted the values.
This removes guesswork and helps ensure your rules match the intended fields.
Related Guide: Troubleshooting wazuh-logtest: Why Alerts Are Missing from JSON Output
Common Parsing Problems with Nested JSON
Although Wazuh’s built-in JSON decoder is highly capable, certain JSON structures can lead to unexpected parsing behavior.
Understanding these common issues can significantly reduce troubleshooting time.
Missing Nested Fields
One of the most common problems is that expected nested fields never appear in the parsed event.
Possible causes include:
- Invalid JSON formatting.
- Unsupported data structures.
- Fields located inside complex arrays.
- Incorrect log source configuration.
- Preprocessing performed before the log reaches Wazuh.
The first troubleshooting step should always be verifying that the original JSON is valid and that the expected fields exist in the incoming log.
Arrays Not Appearing in Alerts
Administrators are often surprised when array values visible in the original JSON do not appear in generated alerts.
This usually occurs because:
- The array contains nested objects.
- Only portions of the array are extracted.
- The rule references an incorrect field.
- The alert only displays selected fields.
Inspecting the decoded event with wazuh-logtest provides a much more accurate picture than relying solely on the alert output.
Unexpected Flattened Field Names
Sometimes the generated field names differ from what administrators expect.
For example:
Instead of:
usernameWazuh may generate:
user.identity.usernameSimilarly:
request.parameters.instanceTypemay be created instead of simply:
instanceTypeAlways use the generated field names rather than assumptions based on the original JSON document.
Duplicate Field Names
Duplicate field names commonly occur inside arrays of objects.
Example:
{
"users": [
{
"username": "alice"
},
{
"username": "bob"
}
]
}Since both objects contain a username field, matching an individual occurrence may not always behave as expected.
When duplicate fields exist, carefully review the parsed output before creating rules that depend on those values.
Unsupported JSON Structures
Although JSON is a standardized format, applications sometimes generate structures that are difficult to process efficiently.
Examples include:
- Deeply recursive objects.
- Nested arrays within nested arrays.
- Very large embedded JSON documents.
- Mixed-type arrays.
- Inconsistent object schemas.
When these structures become problematic, preprocessing the logs before ingestion often produces more reliable results.
Invalid JSON Syntax
Wazuh can only parse valid JSON.
Common syntax problems include:
- Missing commas.
- Missing quotation marks.
- Unclosed braces.
- Unclosed arrays.
- Trailing commas.
- Malformed escape sequences.
Before troubleshooting Wazuh itself, validate the JSON using a trusted JSON validator.
Performance Issues with Very Large JSON Documents
Extremely large JSON events can increase parsing overhead and consume additional CPU and memory on the Wazuh manager.
This is especially common with:
- Kubernetes audit logs.
- AWS CloudTrail management events.
- Microsoft Azure Activity Logs.
- GitHub Enterprise audit logs.
- Large API gateway payloads.
If parsing performance becomes a concern, consider filtering unnecessary fields or reducing log verbosity before ingestion.
Processing only the fields required for detection can improve overall indexing speed, reduce storage consumption, and simplify rule creation.
How to Troubleshoot Nested JSON Parsing Issues
When Wazuh does not extract JSON fields as expected, the problem is usually related to the original log format, field structure, decoder behavior, or rule configuration.
A systematic troubleshooting process helps identify whether the issue occurs during ingestion, decoding, or rule evaluation.
Verify the Original JSON Log
The first step is confirming that the incoming log is valid JSON.
Before troubleshooting Wazuh, examine the raw event and verify:
- The log begins and ends with valid JSON syntax.
- All keys are enclosed in double quotes.
- Nested objects use proper braces (
{}). - Arrays use proper brackets (
[]). - No unexpected characters exist before or after the JSON payload.
For example, this is valid:
{
"event": {
"action": "login"
}
}However, this is invalid:
{
event: {
action: "login",
}
}Common sources of invalid JSON include:
- Custom applications
- API integrations
- Log forwarding agents
- Manual scripts
- Misconfigured Fluent Bit or Logstash pipelines
If the JSON is malformed before reaching Wazuh, the decoder cannot extract nested fields correctly.
Test with wazuh-logtest
wazuh-logtest is one of the most important tools for troubleshooting JSON parsing issues.
It allows you to submit a raw log and view:
- Which decoder matched the event.
- Extracted fields.
- Dynamic fields.
- Rule matches.
- Generated alerts.
Example:
/var/ossec/bin/wazuh-logtestPaste the JSON event:
{
"user": {
"name": "alice"
}
}The output shows how Wazuh interprets the event.
This helps answer questions such as:
- Did the JSON decoder recognize the log?
- Was the nested key extracted?
- What field name was generated?
- Why did my rule not trigger?
Always test with the exact production log format whenever possible. Small differences between test data and real events can cause misleading results.
Enable Decoder Debugging
When normal testing does not reveal the problem, enabling additional debugging can provide more visibility into the decoding process.
Decoder debugging can help identify:
- Which decoder processed the event.
- Whether JSON parsing succeeded.
- Which fields were extracted.
- Where parsing stopped.
Useful troubleshooting sources include:
- Wazuh manager logs.
- Decoder test output.
- Debug-level logging.
The Wazuh manager logs can be monitored with:
tail -f /var/ossec/logs/ossec.logLook for messages related to:
- Decoder failures.
- JSON parsing errors.
- Invalid events.
- Rule loading issues.
Compare Raw Log vs Parsed Output
One of the most common mistakes when troubleshooting JSON parsing is comparing rules against the original JSON instead of the parsed output.
For example, the original event may contain:
{
"cloud": {
"account": {
"id": "123456"
}
}
}But Wazuh may expose:
cloud.account.id = 123456Your rule must reference:
<field name="cloud.account.id">123456</field>not:
<field name="account.id">123456</field>Always compare:
- Raw JSON input.
- Decoder output.
- Rule field names.
This three-step comparison usually reveals field mismatches quickly.
Check Rule Conditions
Even when JSON parsing works correctly, rules may fail because the conditions do not match the extracted fields.
Common rule problems include:
- Incorrect field names.
- Wrong capitalization.
- Incorrect regular expressions.
- Missing parent conditions.
- Incorrect rule dependencies.
For example, if Wazuh extracts:
event.action = CreateUserthis rule works:
<field name="event.action">CreateUser</field>But this does not:
<field name="action">CreateUser</field>because action is not the extracted field name.
Before modifying rules, confirm the actual parsed fields first.
Review Manager Logs
The Wazuh manager logs provide additional information when parsing failures occur.
Check:
tail -f /var/ossec/logs/ossec.logLook for:
- JSON decoder errors.
- Rule syntax errors.
- Decoder loading failures.
- Configuration problems.
- Module ingestion failures.
After modifying decoders or rules, restart the manager:
systemctl restart wazuh-managerThen verify that the configuration loads successfully.
Related Guide: Fixing wazuh-db Worker Thread Crashes
Validate JSON Before Ingestion
For environments collecting large volumes of JSON logs, validating data before ingestion prevents many parsing issues.
Common validation points include:
- API collectors.
- Log forwarders.
- Cloud ingestion pipelines.
- Container logging systems.
Tools commonly used for validation include:
- JSON schema validators.
- Fluent Bit filters.
- Logstash filters.
- Custom scripts.
Validating JSON upstream reduces the amount of malformed data reaching the Wazuh manager and improves overall reliability.
Advanced Techniques for Complex JSON Parsing
Some JSON logs are too complex for straightforward Wazuh processing.
Large cloud audit events, deeply nested API responses, and arrays containing hundreds of objects may require additional processing before they reach the Wazuh manager.
Preprocessing Logs Before Wazuh
Preprocessing transforms complex logs into a format that Wazuh can analyze more efficiently.
Common preprocessing tasks include:
- Removing unnecessary fields.
- Renaming fields.
- Extracting important values.
- Converting arrays into simple fields.
- Normalizing inconsistent schemas.
For example, instead of sending:
{
"users": [
{
"metadata": {
"identity": {
"username": "alice"
}
}
}
]
}a preprocessing step could create:
{
"username": "alice"
}This creates a much simpler detection environment.
Using Logstash or Fluent Bit
External processing tools are commonly used to normalize JSON before forwarding logs to Wazuh.
Logstash
Logstash can:
- Parse JSON.
- Rename fields.
- Remove unnecessary data.
- Split arrays.
- Enrich events.
Example use cases:
- AWS CloudTrail normalization.
- Kubernetes audit processing.
- Large API log transformations.
Fluent Bit
Fluent Bit is widely used in container environments because of its lightweight footprint.
It can:
- Parse JSON logs.
- Modify records.
- Filter fields.
- Forward normalized events.
This makes it particularly useful for Kubernetes environments where applications generate large volumes of structured logs.
Transforming Arrays into Simpler Fields
Arrays are often the biggest challenge when writing Wazuh rules.
Consider:
{
"permissions": [
"admin",
"write",
"delete"
]
}Instead of forcing detection rules to search the array structure, preprocessing can transform it into:
{
"has_admin_permission": true,
"has_delete_permission": true
}This creates simple boolean fields that are easier to detect.
For security monitoring, normalized fields are often more valuable than preserving every detail from the original JSON structure.
Flattening JSON Before Ingestion
Some environments flatten JSON before sending events to Wazuh.
Example:
Original:
{
"host": {
"network": {
"ip": "10.0.0.5"
}
}
}Flattened:
{
"host.network.ip": "10.0.0.5"
}Benefits include:
- Simpler searches.
- Easier rule creation.
- Reduced parsing complexity.
However, excessive flattening can make data less readable, so only flatten fields that are required for detection.
Creating Custom Processing Pipelines
Large organizations often create dedicated pipelines between data sources and SIEM platforms.
A typical architecture:
Cloud Service
|
|
Log Collector
|
|
Processing Pipeline
|
|
Wazuh Manager
|
|
IndexerThe processing layer can:
- Normalize schemas.
- Remove unnecessary fields.
- Add enrichment data.
- Standardize timestamps.
- Reduce event size.
This approach is especially valuable for organizations collecting logs from multiple cloud providers.
Reducing Parsing Complexity
Simplifying logs before ingestion improves:
- Detection accuracy.
- Rule maintainability.
- Indexing speed.
- Storage efficiency.
Recommended approaches:
- Collect only security-relevant fields.
- Remove unused metadata.
- Avoid ingesting massive API payloads.
- Normalize fields across different sources.
- Avoid unnecessary nesting.
A smaller, cleaner event is usually more valuable than a massive event containing information that will never be analyzed.
Performance Considerations When Parsing Large JSON Documents
Complex JSON parsing can impact Wazuh performance, especially in environments processing thousands of events per second.
Understanding the main performance bottlenecks helps maintain a stable deployment.
Dynamic Field Explosion
Dynamic fields are powerful, but excessive field creation can create indexing problems.
A single JSON document containing hundreds or thousands of unique keys can create:
- Large index mappings.
- Increased memory usage.
- Slower searches.
- Higher disk consumption.
This issue is sometimes called field explosion.
Common causes include:
- Dynamic application metadata.
- User-generated JSON fields.
- Large API responses.
- Uncontrolled logging formats.
Reduce unnecessary fields before ingestion whenever possible.
Large Arrays
Large arrays can significantly increase parsing workload.
Examples:
- Thousands of Kubernetes objects.
- Large IAM policy documents.
- Bulk API responses.
- Firewall rule collections.
Large arrays increase:
- Decoder workload.
- Event size.
- Indexing time.
- Storage requirements.
If arrays contain information that is not required for detection, filter them before they reach Wazuh.
Deeply Nested Objects
Deep nesting increases parsing complexity.
Example:
level1.level2.level3.level4.level5.level6.fieldProblems caused by deep structures include:
- Longer field names.
- More complicated searches.
- Harder rule maintenance.
- Increased indexing overhead.
Where possible, normalize deeply nested structures into simpler fields.
Memory Usage
Large JSON events consume additional memory during:
- Parsing.
- Rule evaluation.
- Indexing.
- Storage preparation.
High memory usage may appear as:
- Increased Wazuh manager RAM consumption.
- Slower event processing.
- Delayed alerts.
Monitor system resources when onboarding large JSON sources.
Related Guide: Why Is Wazuh Using High CPU? Troubleshooting Guide
Indexing Performance
After parsing, extracted fields are stored in the Wazuh indexer.
Large and complex JSON documents can affect:
- Indexing throughput.
- Search speed.
- Cluster resource usage.
OpenSearch performance depends heavily on:
- Number of fields.
- Document size.
- Mapping complexity.
- Index configuration.
Related Guide: How to Build a Wazuh Indexer Cluster
Best Practices for High-Volume Environments
For large-scale Wazuh deployments:
- Filter unnecessary JSON fields before ingestion.
- Avoid indexing excessive metadata.
- Normalize cloud logs consistently.
- Monitor index size growth.
- Test new log sources before production deployment.
- Use dedicated indexer resources.
- Keep detection rules focused on important security signals.
A well-designed JSON ingestion pipeline improves both Wazuh performance and analyst efficiency.
By simplifying complex JSON before it reaches the detection engine, organizations can maintain faster searches, cleaner alerts, and more reliable security monitoring.

Be First to Comment