406 Access Denied (Not Acceptable) Hatası

HTTP 406 Not Acceptable, istemcinin (tarayıcı/API istemcisi) gönderdiği Accept/Accept-Language/Accept-Charset gibi başlıklara uygun bir içerik bulunamadığında veya güvenlik katmanları (WAF/ModSecurity/CDN) isteği şüpheli görüp engellediğinde döner. Pratikte 406’yı en çok şu nedenler tetikler:

  • ModSecurity/WAF kuralı (SQLi/XSS paterni sanılan URL, query string, header)
  • Apache MultiViews / içerik pazarlığı (content negotiation) çakışmaları
  • Yanlış/Missing Content-Type ya da framework’te içerik pazarlığı hatası (ör. JSON beklenirken HTML gönderme)
  • CDN/Reverse Proxy güvenlik filtreleri (Cloudflare, Sucuri vb.)
  • Eklenti/tema güvenlik filtresi (WordPress güvenlik eklentileri)

Aşağıdaki adımlarla sebebi hızla saptayıp kalıcı çözüme geçebilirsin.

1) Hızlı Teşhis (Sunucu Logları & Komutlar)

a) İsteği yeniden üret

Tarayıcı gizli modda dene. Ardından curl ile minimal istek at:

curl -I https://alanadiniz.com/istenen/yol

JSON bekleyen endpoint için:

curl -i -H "Accept: application/json" https://alanadiniz.com/api/endpoint

Eğer Accept başlığı eklenince düzeliyorsa sorun içerik pazarlığı tarafında.

b) Web sunucusu logları

  • Apache error log:
    • CentOS/Alma/Rocky: /var/log/httpd/error_log
    • Debian/Ubuntu: /var/log/apache2/error.log
  • Nginx error log: /var/log/nginx/error.log
  • ModSecurity audit log:
    • /var/log/httpd/modsec_audit.log veya /var/log/modsec_audit.log
      Log satırında id: 9xxxxxx gibi bir kural ID görürsen, 406’yı bir ModSecurity kuralı tetiklemiş demektir.

c) Panele göre kısayollar

  • cPanel/WHM: WHM → Security Center → ModSecurity Tools → Hits (bloklanan istek ve Rule ID görünür)
  • Plesk: Web Application Firewall (ModSecurity) bölümünden Audit Log
  • DirectAdmin: Admin Level → ModSecurity / log görüntüleme eklentileri

2) En Yaygın Nedenler ve Çözümler

A) ModSecurity/WAF kaynaklı 406

Belirti: Log’da ModSecurity rule ID’si; Cloudflare WAF Events’te “Blocked”.
Çözüm:

  1. Geçici test: Sadece sorunlu domain için WAF’ı Detection Only (sadece kaydet) moduna al.
    • cPanel/WHM: ModSecurity Configuration → Ruleset: On, Audit: On, Blocking: Off (geçici)
    • Plesk: Web Application Firewall → Mode: Detection only
  2. Kuralı bypass et (nokta atışı):
    Belirli URI için problemli Rule ID’yi devre dışı bırak:

    <LocationMatch "^/api/endpoint">
      SecRuleRemoveById 949110 942100
    </LocationMatch>
    

    (Gerçek Rule ID’lerini audit log’dan al.)

  3. CRS güncelle: OWASP CRS’i güncellemek yanlış-pozitifleri azaltır.
  4. Cloudflare/Sucuri: Security Events ekranından “Allow” kuralı ekle (URI, parametre veya IP bazlı).

Not: WAF’ı tamamen kapatmak yerine kural-bazlı whitelist en iyi uygulamadır.

B) Apache MultiViews / İçerik Pazarlığı

Belirti: Özellikle çok-dilli URL’lerde ya da uzantısız dosyalarda 404 yerine 406.
Çözüm: .htaccess içine MultiViews’ı kapat:

Options -MultiViews

Ayrıca doğru Content-Type ve charset başlıklarını gönderdiğinden emin ol.

C) Framework/Backend (Content Negotiation) Hatası

Belirti: API uçlarında 406; Accept: application/json ile düzeliyor.
Çözüm:

  • Endpoint’in Response Content-Type başlığını doğru ayarla (ör. application/json; charset=utf-8).
  • Spring/Laravel/Django için content negotiation yapılandırmasını kontrol et.
  • Route’un gerçekte ne döndürdüğünü cURL ile incele (-i kullan).

D) WordPress/Güvenlik Eklentileri

Belirti: Belirli admin işlemlerinde, formlarda veya query string uzun olduğunda 406.
Çözüm:

  • Wordfence / iThemes / All-In-One Security’de ilgili firewall kuralını gevşet veya beyaz listeye ekle.
  • Sorunlu eklentiyi geçici kapat, tema/eklenti güncelle.
  • .htaccess temizle (şüpheli rewrite satırlarını çıkar), kalıcı yapılandırmaları geri yaz.

E) CDN / Reverse Proxy Katmanı

Belirti: Kaynak sunucuda 200 dönerken uçta 406.
Çözüm:

  • CDN’de “WAF/Firewall” kural günlüğünü incele; URI/Query/UA bazlı allow kuralı ekle.
  • Header normalizasyonu: Accept, Accept-Language, User-Agent silinmesin/bozulmasın (CDN Transformations).

3) Kalıcı Sağlamlaştırma (Best Practices)

  • Log’ları merkeze topla: modsec_audit + access/error log için rota oluştur (örn. Loki, ELK).
  • Rate limit ve bot koruması: 406 yerine 403/429 ile net politika uygulamak daha okunaklıdır.
  • Güncelleme: OWASP CRS, ModSecurity, güvenlik eklentileri ve çekirdek paketleri güncel olsun.
  • İnce ayar: Sık tetiklenen Rule ID’leri URI-bazlı kaldır; global whitelist yapma.
  • Test: Prod’dan önce staging’de yeni kuralları denerken Detection Only kullan.

Sık Kullanılan Komut ve Snippet’ler

Kuyruğa düşen 406 isteklerini görmek (Apache):

grep " 406 " -R /var/log/httpd/access_log*

ModSecurity audit log’da Rule ID bulmak:

grep -R "id \"9" /var/log/* | grep modsec

Nginx’te yalnızca belirli path için ModSecurity’yi kapatmak (modsec dinamik mod kuruluysa):

location /api/endpoint {
    ModSecurityRuleRemoveById 949110 942100;
    proxy_pass http://app;
}

.htaccess ile MultiViews kapatma:

Options -MultiViews

406 Access Denied (Not Acceptable) Hatası – Sonuç

406 Access Denied/Not Acceptable, çoğunlukla WAF/ModSecurity yanlış-pozitifleri veya içerik pazarlığı uyumsuzluklarından kaynaklanır. Log’dan Rule ID yakalayıp URI’ye özel whitelist uygulamak ve MultiViews’ı devre dışı bırakmak genellikle sorunu kalıcı çözer. API’lerde ise Accept/Content-Type eşleşmesini netleştirmek kilittir.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir