Case 1 below is built from reading the Wazuh 4.14.7 source and the public documentation. The Windows case was measured on a Windows 11 agent. The Limits section says exactly what each covers.
How to check in one minute
The message goes to the active response log of the host where the response ran, the agent or the manager depending on <location>:
grep "Cannot read 'srcip'" /var/ossec/logs/active-responses.log | tail -n 5
Then look at what triggers the response. On the manager:
grep -A8 '<active-response>' /var/ossec/etc/ossec.conf
If it is bound by <level> or <rules_group>, it runs for every matching rule, including rules whose events carry no IP. This lists, per rule ID, the alerts in today's alerts.json that have neither data.srcip nor a Windows ipAddress / destinationIp:
python3 - <<'EOF'
import json, collections
n = collections.Counter()
for line in open('/var/ossec/logs/alerts/alerts.json'):
try:
a = json.loads(line)
except ValueError:
continue
d = a.get('data') if isinstance(a.get('data'), dict) else {}
w = d.get('win') if isinstance(d.get('win'), dict) else {}
e = w.get('eventdata') if isinstance(w.get('eventdata'), dict) else {}
if not ({'srcip'} & d.keys() or {'ipAddress', 'destinationIp'} & e.keys()):
n[a.get('rule', {}).get('id')] += 1
for rule_id, count in n.most_common(20):
print(rule_id, count)
EOF
Any rule ID in that list that also matches your active response binding will produce this message.
Test the response directly, with an address you control (we used the documentation range), through the manager API:
curl -k -X PUT "https://<manager>:55000/active-response?agents_list=<agent id>" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"command":"!netsh.exe","alert":{"data":{"srcip":"203.0.113.78"}}}'
The leading ! runs the executable by name. With "command":"netsh" the 4.14.7 API answered The command used is not defined in the configuration. (error 1652) because no <active-response> block used that command yet. On Windows the log is C:\Program Files (x86)\ossec-agent\active-response\active-responses.log.
Why it happens
In 4.14.7 the response reads the source IP with get_srcip_from_json() in src/active-response/active_responses.c. Reading the code, it does this, in order:
- It needs
parameters.alert.datain its input to be an object. If not, there is no IP. - If
data.win.eventdata.ipAddressis a string, that is the candidate. If not, it triesdata.win.eventdata.destinationIp. - Only if neither Windows field is a string does it read
data.srcip. - The candidate must parse as an IPv4 or IPv6 address. If it does not, there is no IP. There is no fall-back to the next field.
When nothing comes back, firewalls/default-firewall-drop.c writes this line to logs/active-responses.log under the install directory and exits with an error:
Cannot read 'srcip' from data or invalid IP format
In 4.14.7 the text ends with or invalid IP format. Public reports, for example wazuh/wazuh issue 11842, quote the shorter form used in the title of this page.
So there are three practical causes:
- The event has no
srcip. The decoder for that source does not extract one, or it lands under another name. The JSON decoder keeps the key's own name (we saw this inwazuh-logteston 4.14.7 with Nextcloud and Office 365 events), so an address under a key such assrc_ipbecomesdata.src_ip, which this function does not read. - The field exists but is not an IP address, for example a host name.
- Windows events: if
win.eventdata.ipAddressis present as a string but is not a valid address, the function returns nothing without tryingdestinationIpordata.srcip.
What it means for rules that use srcip
The message does not mean your rule failed. The rule matched, the alert was written, and only the response step found nothing to act on. But the same decoded field feeds rules: in the Wazuh decoder documentation srcip is one of the static fields, alongside srcuser, dstip, action, status and others. If a source never decodes srcip, rules that rely on it for that source have nothing to read either.
One measured point about static fields: on 4.14.7 we referenced the static field status as <field name="status"> in a rule. wazuh-analysisd -t failed with Failure to read rule 44732. Field 'status' is static and a CRITICAL (1220), and the manager would not start. The static tag <status> loaded cleanly. srcip is in the same static list; we have not run that exact case for srcip. In rules, use the <srcip> option, not <field name="srcip">.
On Windows agents (4.14.7, measured): every IP fails
From a 4.14.7 manager we sent active responses to a Windows 11 agent running 4.14.7, through the API as shown above, and read the agent's active-responses.log:
| Alert sent | netsh.exe | route-null.exe |
|---|---|---|
only data.win.eventdata.ipAddress = 203.0.113.77 | Cannot read 'srcip' from data | Cannot read 'srcip' from data |
only data.srcip = 203.0.113.78 | Cannot read 'srcip' from data | Cannot read 'srcip' from data |
Word for word, from the agent:
2026/10/03 19:51:29 active-response/bin/netsh.exe: Cannot read 'srcip' from data
2026/10/03 19:51:39 active-response/bin/route-null.exe: Cannot read 'srcip' from data
The data.srcip row rules out the field name: a plain, valid address was rejected too. Afterwards there was no Wazuh firewall rule and no route for either address on the machine. Note that the Windows responses print the short form of the message, without or invalid IP format.
Why, from the code. At v4.14.7, netsh.c (line 76) and route-null.c (line 29) both call get_srcip_from_json(), which checks the address with get_ip_version(), which calls getaddrinfo() (active_responses.c, line 576). We found no WSAStartup call in active_responses.c, netsh.c or route-null.c; on Windows, the socket functions need it first. That fits the cause proposed in wazuh/wazuh issue 38739, still open. This is our reading of the code plus the result above, not a debugger run.
Workaround: we found no central workaround you can apply from the manager. The check fails before netsh runs, whatever field carries the IP, and the Fix section below (binding, decoder) does not change that on Windows.
Fix
For case 1 (no usable IP in the alert). For the Windows case, see above.
1. Bind the response only to rules whose events carry an address. Use <rules_id>, which the documentation describes as limiting the command to when the listed rules fire, instead of a level or group that also catches rules without an IP:
<active-response>
<command>firewall-drop</command>
<location>local</location>
<rules_id>100100</rules_id> <!-- your rule ID(s) -->
<timeout>600</timeout>
</active-response>
2. Make the decoder name the field srcip for the sources you want to block on. For a regex decoder, <order> maps each capture group to a field name, and srcip is one of the names it accepts. Test the decoder with wazuh-logtest and confirm srcip appears in the decoding phase before relying on the response.
3. Check the value is an address. If the field holds a host name or a placeholder, the response cannot use it, whatever the binding.
Limits of what we measured
What this page says about the message comes from reading the 4.14.7 source (active_responses.c, active_responses.h, firewalls/default-firewall-drop.c) and the public documentation. For case 1 we have not triggered the message on a running Linux agent or manager, and have not measured which releases print the shorter text. The Windows case was measured on one Windows 11 Pro agent running 4.14.7 with a 4.14.7 manager, by calling the responses through the API; we did not measure 4.14.8 or earlier releases, and the WSAStartup explanation is from reading the code, not a debugger. The Python check above is a plain reader of alerts.json; it does not know your active response binding. The one measured item is the static-field load failure, and we measured it for status, not for srcip.