ModSecurity v2.9.12 “Skipping request since there is nowhere to write to” despite valid SecAuditLog configuration
Hi,
On Amazon Linux 2023 (AArch64) using ModSecurity v2.9.12 with Apache 2.4.65, audit logs fail to write even with valid configuration and writable path. Debug logs report:
[15/Oct/2025:13:55:40.259888 +0200] [10.104.19.109/sid#aaaae39e0938][rid#ffff18026b80][/health/status][4] Audit log: Logging this transaction. [15/Oct/2025:13:55:40.259892 +0200] [10.104.19.109/sid#aaaae39e0938][rid#ffff18026b80][/health/status][4] Audit log: Skipping request since there is nowhere to write to.
Environment:
OS: Amazon Linux 2023 (latest patched)
Architecture: aarch64
Apache version: httpd 2.4.65-1.amzn2023.0.1
ModSecurity version: 2.9.12-1.amzn2023.0.1
SELinux: disabled
Config (minimal reproduction):
<IfModule security2_module>
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off
SecDebugLog /var/log/httpd/modsec_debug_test.log
SecDebugLogLevel 5
SecAuditEngine On
SecAuditLogRelevantStatus ".*"
SecAuditLogType Serial
SecAuditLog /var/log/httpd/modsec_audit_test.log
SecRule ARGS:testparam "@streq attack" "id:1,phase:2,deny,log,auditlog,msg:action_detected,ctl:debugLogLevel=9"
</IfModule>
Apache reports Syntax OK
Steps to Reproduce:
Install httpd + mod_security on Amazon Linux 2023.
Apply minimal config above.
Restart httpd and send any request.
Observe debug log.
Expected Result: Audit log file (SecAuditLog) should receive entries.
Actual Result: Log is skipped with nowhere to write to even though the file exists and is writable.
Additional Notes:
No SELinux denials or permission errors.
Hi @tinhutins,
thanks for sending this report.
Before that message, have you seen any similar one like this?
Audit log: Failed writing (requested ...
Hi @airween
thanks for the quick reply.
We haven’t seen any log entry like:
Audit log: Failed writing (requested ...)
in the modsec_debug.log.
Here’s the full relevant config:
SecResponseBodyAccess Off
SecDebugLog /var/log/httpd/modsec_debug.log
SecDebugLogLevel 5
#SecDebugLogLevel 9
SecAuditEngine On
# SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus ".*"
#SecAuditLogRelevantStatus "^(?:4(?!04|05|00))"
SecAuditLogParts ABIJDEFHZ
SecAuditLogType Serial
SecAuditLog /var/log/httpd/modsec_audit.log
SecArgumentSeparator &
SecCookieFormat 0
SecTmpDir /var/lib/mod_security
SecDataDir /var/lib/mod_security
The situation is:
modsec_debug.log works fine — it gets populated with debug information.
modsec_audit.log is created automatically when missing, but it always stays empty, no matter what configuration or permissions we try (Serial, Concurrent, different statuses, permissions even 777, etc.).
Permissions and ownership on /var/log/httpd and /var/lib/mod_security seems correct (apache:apache, 700).
So in short: debug logging works, but audit logging never writes anything, even though the audit file itself is created on restart.
Full log for one transaction :
[16/Oct/2025:07:44:21.547070 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Initialising transaction (txid aPCGNYBNFofHNCUXPKq7TwAAAAQ).
[16/Oct/2025:07:44:21.547124 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Transaction context created (dcfg aaab00bd7430).
[16/Oct/2025:07:44:21.547129 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Processing disabled, skipping (hook request_early).
[16/Oct/2025:07:44:21.547248 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Processing disabled, skipping (hook request_late).
[16/Oct/2025:07:44:21.547314 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Hook insert_filter: Processing disabled, skipping.
[16/Oct/2025:07:44:21.556688 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Initialising logging.
[16/Oct/2025:07:44:21.556733 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Starting phase LOGGING.
[16/Oct/2025:07:44:21.556743 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Recording persistent data took 0 microseconds.
[16/Oct/2025:07:44:21.556747 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Audit log: Logging this transaction.
[16/Oct/2025:07:44:21.556752 +0200] [10.104.19.109/sid#aaab014733d8][rid#ffff5c06c940][/health/status][4] Audit log: Skipping request since there is nowhere to write to.
Do you have any hints on what could prevent audit events from actually being written in this situation?
We haven’t seen any log entry like:
Audit log: Failed writing (requested ...)in the modsec_debug.log.
sorry, I forget: in the error.log?
The situation is:
modsec_debug.log works fine — it gets populated with debug information.
modsec_audit.log is created automatically when missing, but it always stays empty, no matter what configuration or permissions we try (Serial, Concurrent, different statuses, permissions even 777, etc.).
Permissions and ownership on /var/log/httpd and /var/lib/mod_security seems correct (apache:apache, 700).
So in short: debug logging works, but audit logging never writes anything, even though the audit file itself is created on restart.
Full log for one transaction :
...
Do you have any hints on what could prevent audit events from actually being written in this situation?
Actually, I don't. Yesterday I checked the code, and (as I remember) there can be two situations:
- the module can't open the file at startup, and the FD (file descriptor) will be NULL; this does not fit, because you wrote that the file is created when it's missing
- the module opened the audit.log successfully, but can't write; then it closes and set the FD to NULL
Unfortunately I can't check this with your setup, because I don't have any aarch64 arch machine. If there is any chance to get a login for that machine, I could try to investigate the issue there.
Hi @airween
Nothing similar shows up in error.log either — here’s what we get on startup:
[Thu Oct 16 07:48:25.730768 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity for Apache/2.9.12 (http://www.modsecurity.org/) configured.
[Thu Oct 16 07:48:25.730779 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity: APR compiled version="1.7.5"; loaded version="1.7.5"
[Thu Oct 16 07:48:25.730783 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity: PCRE2 compiled version="10.40 "; loaded version="10.40 2022-04-14"
[Thu Oct 16 07:48:25.730786 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity: LUA compiled version="Lua 5.4"
[Thu Oct 16 07:48:25.730789 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity: YAJL compiled version="2.1.0"
[Thu Oct 16 07:48:25.730791 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity: LIBXML compiled version="2.10.4"
[Thu Oct 16 07:48:25.730793 2025] [security2:notice] [pid 122656:tid 122656] ModSecurity: Status engine is currently disabled, enable it by set SecStatusEngine to On.
[Thu Oct 16 07:48:25.806244 2025] [mpm_event:notice] [pid 122656:tid 122656] AH00489: Apache/2.4.65 (Amazon Linux) OpenSSL/3.2.2 Communique/4.3.7 configured -- resuming normal operations
Summary:
No errors in error.log.
We have another Amazon Linux 2023 (aarch64) instance in a different environment (test) running the same httpd, modsecurity version and modsecurity logging configuration — and there the audit log works fine.
We can’t share direct access, but can run additional diagnostics (e.g. strace, level 9 debug in modsec) if that helps.
We have another Amazon Linux 2023 (aarch64) instance in a different environment (test) running the same httpd, modsecurity version and modsecurity logging configuration — and there the audit log works fine.
That's very strange...
We can’t share direct access, but can run additional diagnostics (e.g. strace, level 9 debug in modsec) if that helps.
Sure, I see. Unfortunately debug log won't contain any relevant information, only the error.log.
I would rebuild the module with CFLAGS="-O0 -g" flag at ./configure (beside the other flags) or if you install the module as a package, then probably the OS provides a dbgsym package too. Then start httpd with no-fork mode (-X if I'm not wrong) with gdb. Before that you should find this message in source, and set breakpoints before that lines.
Yeah, it's a "good game", but I'm afraid there won't be other chance to get information about this behavior.
Hi @airween
We are trying to inspect ModSecurity audit logs at runtime using GDB on Amazon Linux.
Here is what we have tried:
Checked available functions:
(gdb) info functions modsecurity
apr_status_t modsecurity_process_phase(modsec_rec *, unsigned int);
static apr_status_t modsecurity_tx_cleanup(void *);
apr_status_t modsecurity_request_body_retrieve(modsec_rec *, msc_data_chunk **, long, char **);
apr_status_t modsecurity_request_body_retrieve_start(modsec_rec *, char **);
(gdb) info functions audit
void sec_audit_logger_json(modsec_rec *);
void sec_audit_logger_native(modsec_rec *);
static int sec_auditlog_write.isra.0(modsec_rec *, const char *, unsigned int);
Attempted GDB breakpoint and commands:
set breakpoint pending on
break sec_audit_logger_native
commands
printf "\n=== Audit log triggered ===\n"
bt 3
print msr
print msr->auditlog_id
print msr->r->uri
print msr->r->method
continue
end
continue
Breakpoint is hit when requests are made.
GDB prints:
Thread 32 "httpd" hit Breakpoint 1, sec_audit_logger_native (msr=0xffff48127778) at /usr/src/debug/mod_security-2.9.12-1.amzn2023.0.1.aarch64/apache2/msc_logging.c:1535
1535 void sec_audit_logger_native(modsec_rec *msr) {
Invalid argument syntax
Any tips for inspecting ModSecurity structures safely without causing GDB syntax errors?
Hi again @airween,
Following up on your previous suggestion about rebuilding with CFLAGS="-O0 -g" or using a dbgsym package.
We’re running Amazon Linux 2023 (aarch64), and we have all the related debug packages installed from the official repos:
httpd-core-debuginfo-2.4.65-1.amzn2023.0.1
httpd-debuginfo-2.4.65-1.amzn2023.0.1
httpd-debugsource-2.4.65-1.amzn2023.0.1
mod_security-debuginfo-2.9.12-1.amzn2023.0.1
mod_security-debugsource-2.9.12-1.amzn2023.0.1
Amazon Linux doesn’t ship separate dbgsym packages, only debuginfo and debugsource, so these should be the equivalents.
We started httpd -X under GDB and set a breakpoint at sec_audit_logger_native(modsec_rec *msr), which triggers correctly, but any attempt to inspect fields such as msr->auditlog_id or msr->r->uri results in:
Invalid argument syntax
So it seems GDB can reach the symbol but not dereference the structure.
Is there a recommended way to safely inspect the contents of modsec_rec (or request_rec) when using packaged debuginfo builds? Or does this require a rebuild of ModSecurity specifically with -O0 -g to make those structures fully accessible?
Thanks again for your time and guidance!
Could you try this?
set breakpoint pending on
break sec_audit_logger_native
commands
silent
set language c
frame 0
printf "\n=== Audit log triggered ===\n"
printf "msr=%p\n", msr
# Guard against NULL
if msr != 0
# Show audit id
p (char *)((struct modsec_rec *)msr)->auditlog_id
# Show request_rec pointer + a couple of hot fields
set $r = (request_rec *)((struct modsec_rec *)msr)->r
printf "r=%p\n", $r
if $r != 0
x/s $r->method
x/s $r->uri
x/s $r->unparsed_uri
x/s $r->args
end
end
continue
end
continue
If that doesn't work, see if msr can be read:
info sharedlibrary mod_security
info address sec_audit_logger_native
ptype msr
whatis msr
You should see msr as modsec_rec *. If ptype msr itself errors, GDB isn’t seeing the type (mismatched debuginfo or LTO/stripped CU).