sfw/fix
406 Not Acceptable medium

ModSecurity "406 Not Acceptable" (WAF rule blocked)

A ModSecurity OWASP rule matched your request payload, decided it looked like an attack, and returned 406 (or 403).

What you see

Not Acceptable!
An appropriate representation of the requested resource could not be found on this server.

What’s actually happening

A specific action breaks — saving a post with code in it, submitting a form with an apostrophe or angle bracket, hitting a page with a long query string — and the server returns 406 (some setups use 403). The rest of the site is fine. It's reproducible: the same payload fails every time, a plain payload works. The give-away is a matching entry in the ModSecurity audit log at the exact second of the request.

Common causes

  • An OWASP Core Rule Set SQLi signature (rule IDs in the 942xxx range) matched a quote, comment marker, or SQL keyword in legitimate form data.
  • An XSS signature (941xxx) tripped on HTML or JavaScript a user pasted into a textarea or a page builder field.
  • A nulled or sloppy plugin sends raw resources or odd request bodies that resemble an attack pattern.
  • Paranoia level set too high in the CRS, so borderline-normal input gets flagged.
  • Default SecDefaultAction set to status:406 — which is why you see 406 rather than the more common 403.

How to fix it

  1. Find the rule that firedRead the audit log: on cPanel/Apache it's /usr/local/apache/logs/modsec_audit.log (or /var/log/httpd/modsec_audit.log), on LiteSpeed check the WHM ModSecurity Tools hit list. Look for the [id "NNNNNN"] and [msg "..."] on the blocked request. That ID is the one to whitelist.
  2. Confirm it's a false positiveReproduce the request and verify the flagged input is genuinely yours — a customer name with an apostrophe, code in a snippet field — not an actual injection attempt. Don't whitelist a rule that's catching a real attack on a vulnerable endpoint.
  3. Whitelist by rule ID scoped to the URL or parameterAdd an exclusion in REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf, e.g. SecRule REQUEST_URI "@beginsWith /wp-admin/post.php" "id:1000001,phase:1,pass,nolog,ctl:ruleRemoveById=942100". Scope to the path or parameter — never disable the rule globally.
  4. Reload and retestRestart Apache/LiteSpeed (systemctl restart httpd or via WHM). Resubmit the exact request that failed and confirm a 200. Re-check the audit log to make sure no other rule fired next in line.

Stop it recurring

Tune CRS exclusions per-endpoint instead of dropping paranoia level site-wide, so the WAF still blocks real SQLi/XSS everywhere else.

Related errors