Skip to content
Bloga Dönün
Eğitimler

HTTP Durum Kodları: 1xx-5xx eksiksiz çevrimiçi rehber

1xx'ten 5xx'e kadar HTTP durum kodlarının eksiksiz referansı: gerçek örnekler, sık yapılan hatalar (401 vs 403, 301 vs 302) ve SEO etkisi. Hemen inceleyin.

14 dakika okuma

HTTP durum kodları kopya kâğıdı: her kod açıklamasıyla (1xx-5xx)

DevTools’u açıyorsunuz, Network sekmesinin yarısı kıpkırmızı. Endpoint’iniz canlıda 502, lokalde 200 döndürüyor; Slack’ten bir iş arkadaşı az önce “bu 401 mi olmalı, 403 mü?” diye sordu. HTTP durum kodları basit görünür: üç hane, beş kova. Ama yanlış seçim bilgi sızdırır, SEO’yu bozar ve nöbet vardiyalarını çekilmez hâle getirir.

Bu rehber, sahada çalışan geliştiriciler için bir HTTP durum kodları kopya kâğıdıdır. Üç şey bulacaksınız: (1) gerçekten karşılaştığınız her kodu içeren hızlı referans tablosu, (2) en çok karıştırılan çiftler için karar matrisleri (301 vs 302, 401 vs 403, 404 vs 410, 502 vs 504) ve (3) curl, fetch ve Python requests ile durum kodlarını nasıl inceleyeceğinizi gösteren bir araç bölümü. Aşağıdaki her kod, güncel HTTP semantik standardı olan RFC 9110 ve IANA HTTP Status Code Registry temel alınarak hazırlandı.

Hızlı referans: tüm HTTP durum kodları bir bakışta

Canlı ortamda karşılaşacağınız kodlar aşağıda sınıflarına göre gruplandı. Bu tabloyu yer imlerinize ekleyin; yazının geri kalanı zor olanları açıklıyor.

KodAdıNe zaman görürsünüz
100ContinueExpect: 100-continue ile büyük bir POST gövdesi gönderirken
101Switching ProtocolsWebSocket el sıkışması, HTTP/2 yükseltmesi
103Early HintsSunucu, asıl yanıttan önce Link header’ları iletir
200OKGET, PUT, PATCH için varsayılan başarı
201CreatedKaynak yaratan POST (Location döner)
202AcceptedAsenkron iş kuyruğa alındı, henüz tamamlanmadı
204No ContentDELETE başarısı, gövde döndürmeyen PUT
206Partial ContentRange isteği, video atlama, devam ettirilebilir indirme
301Moved PermanentlyEski URL emekliye ayrıldı, arama motorları link gücünü aktarır
302FoundGeçici yönlendirme, orijinal URL hâlâ kanonik
303See OtherForm POST’undan sonra Post/Redirect/Get deseni
304Not ModifiedETag veya If-Modified-Since eşleşen koşullu GET
307Temporary Redirect302 gibi, ama method ve gövde korunur
308Permanent Redirect301 gibi, ama method ve gövde korunur
400Bad RequestHatalı JSON, eksik zorunlu alan, şema başarısızlığı
401UnauthorizedKimlik bilgisi yok veya token süresi dolmuş
403ForbiddenKimlik doğrulandı ama izin yok
404Not FoundKaynak yok (veya saklıyorsunuz)
405Method Not AllowedYalnızca GET kabul eden endpoint’e POST (Allow header’ı zorunlu)
408Request Timeoutİstemci, isteği göndermeyi çok uzattı
409Conflictİyimser kilit hatası, yinelenen anahtar
410GoneKaynak kalıcı silindi, geri gelmeyecek
415Unsupported Media TypeYanlış Content-Type, ör. JSON API’ye XML
422Unprocessable ContentSöz dizimi geçerli, anlam geçersiz (doğrulama hatası)
425Too EarlyTLS 1.3 early-data tekrar saldırısı riski
428Precondition RequiredSunucu, kayıp güncellemeyi önlemek için If-Match ister
429Too Many RequestsHız sınırlaması (Retry-After zorunlu)
451Unavailable for Legal ReasonsDMCA, GDPR kaldırması, coğrafi engel
500Internal Server ErrorKodunuzda yakalanmamış istisna
501Not ImplementedMethod veya özellik desteklenmiyor (REST’te nadir)
502Bad GatewayYukarı akış geçersiz yanıt verdi
503Service UnavailableBakım modu veya aşırı yük
504Gateway TimeoutYukarı akış zamanında yanıt vermedi
507Insufficient StorageWebDAV’da disk doldu
508Loop DetectedWebDAV’da sonsuz yönlendirme veya özyineleme
511Network Authentication RequiredOtel/havalimanı WiFi’sinde captive portal

Yazının geri kalanı her sınıfı karar matrisleri, anti-desenler ve yanlış seçimin SEO sonuçlarıyla açıklıyor.

HTTP durum kodları nasıl çalışır (3 haneli anatomi)

Neden üç hane?

HTTP durum kodları üç ondalık haneden oluşur, çünkü HTTP/0.9’un sabit genişlikli bir sinyale ihtiyacı vardı: ayrıştırıcının üzerinde hızlıca dallanabileceği kadar küçük, yeni kodlara yer bırakacak kadar büyük. Üç hane 900 olası değer verir (100–999); bu fazlasıyla yeterli. IANA kayıt defteri bugün bunların yalnızca 60 kadarını kullanıyor.

İlk hane sınıftır. İkinci ve üçüncü, o sınıfın içindeki belirli koddur. 418’i tanımayan bir istemci, kodu genel bir 4xx gibi ele almalıdır. RFC 9110 §15 bunu net biçimde belirtir: istemciler tanımadıkları kodları kendi sınıflarının x00’ı olarak işlemek zorundadır.

Beş kategori bir bakışta

SınıfAnlamıGövde gerekli mi?Varsayılan olarak önbelleklenir mi?
1xxInformational — geçici, devamı geliyorHayırHayır
2xxSuccess — istek anlaşıldı ve kabul edildiÇoğu zamanMethod’a göre değişir
3xxRedirection — ek işlem gerekiyorİsteğe bağlı301, 308 evet; 302, 307 hayır
4xxClient error — hata sizde, isteği düzeltinEvet (açıklayın)Genelde hayır
5xxServer error — hata bizde, yeniden denemek işe yarayabilirEvet (açıklayın)Hayır

“Varsayılan olarak önbelleklenir mi?” sütunu önemli. CDN’ler ve tarayıcılar 301 ve 308 yanıtlarını agresifçe ve sonsuza kadar önbelleğe alır. Canlıda yanlış yönlendirme kodunu seçmek geri alınması güç bir karardır, çünkü kullanıcılar yönlendirmeyi kendi tarayıcılarında önbellekte tutar. Bu konuyu SEO bölümünde tekrar ele alacağız.

URL yapısının (yönlendirme kodlarının üzerinde çalıştığı yapı) ayrıntısına inmek isterseniz, URL kodlama ve çözme yüzde-kodlamasını, query string’leri ve bir URL’yi geçerli kılan bayt seviyesindeki boru hattını adım adım anlatıyor.

1xx — informational (gerçekten ne zaman görürsünüz)

Birçok geliştirici yıllarca doğrudan bir 1xx görmeden çalışır. Bunlar geçici yanıtlardır: sunucu, istemciye “hâlâ buradayım, devam et” diyor. Tarayıcı DevTools genellikle bunları gizler ve çoğu HTTP kütüphanesi bunları nihai yanıta katlayarak gösterir.

Aşağıdaki kodları doğrulamak istediğinizde MDN HTTP yanıt durum referansı kullanışlı bir çapraz referanstır.

100 Continue

İstemci, header’larında Expect: 100-continue gönderir ve büyük bir istek gövdesini iletmeden önce bekler. Sunucu gövdeyi kabul etmeye hazırsa 100 Continue ile yanıtlar; isteği zaten reddedecekse bir 4xx döner. Bu, büyük yüklemelerde bant genişliğinden tasarruf sağlar: sunucu eksik bir header yüzünden isteği reddedecekse 200 MB’ı göndermenin anlamı yok.

curl -v -H "Expect: 100-continue" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @big-file.bin \
  https://api.example.com/upload

Verbose çıktıda < HTTP/1.1 100 Continue görmüyorsanız, büyük olasılıkla istemciniz header’ı kırpıyor ya da sunucu bunu desteklemiyordur.

101 Switching Protocols

Bir HTTP bağlantısını WebSocket veya HTTP/2 bağlantısına dönüştüren el sıkışma. İstemci Upgrade: websocket gönderir, sunucu 101 Switching Protocols ile yanıtlar ve o andan itibaren bağlantı farklı bir protokolle konuşur. Bunu herhangi bir sohbet uygulamasının, canlı panonun veya ortak çalışma aracının Network sekmesinde göreceksiniz.

103 Early Hints

Yeni sayılabilecek bir kod (RFC 8297, 2017): sunucunun, asıl yanıt hazır olmadan önce preload ipuçları için Link header’ları göndermesine izin verir. Tarayıcı, sunucu hâlâ render ederken CSS ve JS’i indirmeye başlar. 2026 itibarıyla Cloudflare, Fastly ve Vercel 103’ü canlıda destekliyor; Chrome’da kullanımdan kaldırılan HTTP/2 server push’un modern alternatifidir.

HTTP/1.1 103 Early Hints
Link: </styles.css>; rel=preload; as=style
Link: </app.js>; rel=preload; as=script

HTTP/1.1 200 OK
Content-Type: text/html
...

Anti-desen kontrolü. Beklediğiniz hâlde istemciniz 1xx kodlarını hiç görmüyorsa, sorun genellikle bir ters proxy’dir. Eski nginx sürümleri Expect: 100-continue ve 103 Early Hints başlıklarını kırpar. Sunucunun bozuk olduğunu varsaymadan önce proxy yapılandırmanızı kontrol edin.

2xx — success (sadece 200’ün ötesinde)

Her şey için 200 OK döndürmek, REST API’lerinde en yaygın kod kokusudur. 2xx ailesi, istemcileri akıllılaştıran ve önbellekleri verimli kılan anlamsal bilgi taşır.

200 OK

Varsayılan. GET kaynağı döner, PUT güncellenmiş kaynağı döner (veya 204), PATCH yamalanmış kaynağı döner. Daha özgül bir kod kullanmak için belirli bir nedeniniz yoksa 200 kullanın.

201 Created

Yeni bir kaynak yaratan POST, 201 ile birlikte yeni kaynağı işaret eden bir Location header’ı dönmelidir. RESTful istemciler, az önce yarattıkları şeyin kanonik URL’sini bu şekilde keşfeder.

HTTP/1.1 201 Created
Location: /api/users/42
Content-Type: application/json

{"id": 42, "name": "Ada Lovelace"}

202 Accepted

Sunucu isteği kabul etti ama işlemeyi bitirmedi. Asenkron işler için kullanın: istemci poll yapmalı, bir webhook’a abone olmalı veya status endpoint’ini kontrol etmelidir. Gövdede bir job ID ile birlikte kullanın.

204 No Content

Başarı, gövde yok. DELETE için yaygındır (kaynak gitti, ne döneceksiniz?) ve istemcinin yeni durumu zaten bildiği PUT işlemleri için. Bir form gönderimi 204 döndürürse tarayıcılar mevcut sayfayı değiştirmez; single-page uygulamalardaki “gönder ve unut” işlemleri için kullanışlıdır.

206 Partial Content

Range istekleri için döner: istemci Range: bytes=1000-2000 header’ı ile 1000-2000 baytlarını istemiştir ve sunucu yalnızca o dilimle yanıt verir. Video akışı, devam ettirilebilir indirmeler ve HTTP tabanlı dosya senkronizasyonu hep 206’ya dayanır.

Karar: POST için 200 vs 201 vs 204

SenaryoKodGövde
POST yeni bir kaynak yaratıyor201 CreatedYeni kaynak (veya yalnızca ID) + Location
POST asenkron iş tetikliyor, sonuç hazır değil202 AcceptedJob ID, poll URL
POST kaynaksız bir eylem (ör. /login)200 OKEylem sonucu (token, durum)
POST başarılı ama yanıt boş204 No Content(yok)

200 ile 201 arasında karar veremiyorsanız şunu sorun: “Sunucu, artık kendi URL’sine sahip yeni bir kaynak mı yarattı?” Cevap evetse 201. Hayırsa 200.

3xx — redirection (301 vs 302 vs 307 vs 308)

Yönlendirmeler en çok yanlış kullanılan sınıftır. 301, 302, 307 ve 308 arasındaki farklar üç bağımsız soruya iner: taşınma kalıcı mı, method korunuyor mu ve yanıt önbelleklenebilir mi.

301 Moved Permanently

Kaynak taşındı ve geri gelmeyecek. Arama motorları link gücünü yeni URL’ye aktarır. Tarayıcılar ve CDN’ler 301 yanıtını süresiz önbelleğe alır. /old’u 301 ile /new’a yönlendirip sonra fikrinizi değiştirirseniz, önbelleklenmiş yönlendirmesi olan kullanıcılar sonsuza kadar (ya da önbelleklerini temizleyene kadar) /new’a gitmeye devam eder.

Tarayıcılar tarihsel olarak 301’de istek method’unu yeniden yazabilir (POST → GET); bunu düzeltmek için HTTP/1.1, 308’i tanıttı.

302 Found

Geçici yönlendirme. Orijinal URL hâlâ kanoniktir; arama motorları orijinali indekslemeye devam etmelidir. A/B test yönlendirmesi, bakım sayfaları veya “devam etmek için giriş yapın” akışları için kullanın.

301 gibi, tarayıcılar 302’de POST’u tarihsel olarak GET’e yeniden yazardı. Bir POST’u yönlendirip POST olarak tutmak istiyorsanız, bunun yerine 307 kullanın.

303 See Other

Method’u her zaman GET’e yeniden yazar. Post/Redirect/Get deseni: form /submit’e POST eder, sunucu Location: /thank-you ile 303 döner, tarayıcı GET /thank-you yapar. Teşekkür sayfasını yenilemek formu yeniden göndermez. 303 tam olarak bunun için tasarlandı.

304 Not Modified

Koşullu yanıt. İstemci If-None-Match: "abc123" (veya If-Modified-Since) gönderir, sunucu kaynağın değişip değişmediğini kontrol eder ve değişmediyse gövdesiz 304 döner. Tarayıcı önbelleklenmiş kopyasını kullanır. Her CDN ve önbellek katmanının sitenizi hızlı tutma yöntemi budur.

307 Temporary Redirect

302 gibi, ama method değişmemelidir. POST, POST kalır, gövde korunur. GET olmayan bir istekte geçici yönlendirme istediğinizde bunu kullanın.

308 Permanent Redirect

301 gibi, ama method değişmemelidir. POST/PUT kabul eden API’lerde kalıcı yönlendirmeler için modern ve daha güvenli seçim.

Karar matrisi: hangi yönlendirme kodu?

Kalıcı (sonsuza kadar önbellekle)Geçici (önbellekleme)
Method GET’e değişebilir301 Moved Permanently302 Found
Method aynı kalmalı308 Permanent Redirect307 Temporary Redirect

Özel durum: özellikle POST → GET istiyorsanız (Post/Redirect/Get deseni), 303 See Other kullanın.

Tarayıcı navigasyonlu HTML sayfaları için 301 ve 302 genellikle uygundur, çünkü GET, GET olarak kalır. API’ler ve formlar için, sürpriz method yeniden yazımlarından kaçınmak adına 308 ve 307’yi tercih edin.

4xx — client errors (doğrusunu seçmek)

4xx, istemcinin bir şeyi yanlış yaptığı anlamına gelir. 4xx sözcük dağarcığınız ne kadar zenginse, API’nizi kullanmak o kadar kolay olur: istemciler hata metinlerini ayrıştırmak yerine kod üzerinde dallanabilir.

400 Bad Request

Genel söz dizimi hatası. Hatalı JSON, yapısal düzeyde eksik zorunlu alan, sunucunun ayrıştıramadığı istek. İstek ayrıştırılıyor ama iş doğrulaması başarısız oluyorsa 422’yi tercih edin.

401 Unauthorized vs 403 Forbidden

HTTP’de en çok karıştırılan çift. Ayrım, gördüğünüz anda basittir:

  • 401 Unauthorized: istek geçerli kimlik doğrulamadan yoksun. Sunucu kim olduğunuzu bilmiyor. Kimlik bilgilerini yeniden göndermek (veya token’ı yenilemek) sorunu çözebilir. Yanıt, RFC 9110 §15.5.2 uyarınca bir WWW-Authenticate header’ı içermek zorundadır.
  • 403 Forbidden: sunucu kim olduğunuzu biliyor ve yine de reddediyor. İsteği yeniden göndermek işe yaramaz. Farklı kimlik bilgilerine veya farklı izinlere ihtiyacınız var.
GördüğünüzDoğru olan
WWW-Authenticate: Bearer ile 401Token yok, süresi dolmuş veya geçersiz
Başarılı girişten sonra 403Giriş yapılmış ama bu kullanıcı bu kaynağa erişemez
Başarılı girişten sonra 401Bug: büyük olasılıkla 403 istiyorsunuz

Anti-desen: 403-as-404. Bazı siteler, kimliği doğrulanmamış bir kullanıcı /admin/dashboard’u istediğinde 403 döner. Bu, /admin/dashboard’un varlığını sızdırır. GitHub bu sorunu, üyesi olmadığınız özel depolar için 404 döndürerek çözer; kaynak sizin perspektifinizden “yok”. Bu, bir bug değil, bilinçli bir bilgi gizleme tercihidir.

404 Not Found vs 410 Gone

İkisi de “bu kaynak burada değil” der. Fark, kalıcılık ve SEO’dadır.

  • 404 Not Found: var olabilir, olmayabilir, geri gelebilir. Arama motorları kontrol etmeye devam eder.
  • 410 Gone: buradaydı, kasten kaldırıldı, geri gelmeyecek. Arama motorları indeksten çok daha hızlı düşürür.

Bir ürün sayfasını silip Google’ın indeksinden hemen çıkarmak istiyorsanız doğru çağrı 410’dur. Bir URL yalnızca geçici olarak bozuksa 404 yeterlidir.

405 Method Not Allowed

URL var ama bu method’u kabul etmiyor. Yanıt, desteklenen method’ları listeleyen bir Allow header’ı içermek zorundadır.

HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD, OPTIONS
Content-Type: application/json

{"error": "POST is not allowed on this endpoint"}

Allow header’ını unutmak, elle yazılmış REST API’lerinde en yaygın sözleşme ihlalidir.

408 Request Timeout

İstemci bir isteği göndermeye başladı ve sonra sustu. Sunucu pes etti. 504 Gateway Timeout’tan farklıdır; o yukarı akışla ilgilidir, 408 ise “siz, istemci olarak, çok uzattınız” demektir.

409 Conflict

İstek, mevcut durumla çelişiyor. En yaygın kullanım: iyimser kilitleme. İstemci If-Match: "etag-v3" gönderir ve sunucunun mevcut ETag’i "etag-v4"’tür, dolayısıyla güncelleme 409 ile reddedilir.

410 Gone

Yukarıya bakın: kalıcı silme. Yumuşak silinmiş kayıtları arama indekslerinden çıkarmak için kullanışlıdır.

415 Unsupported Media Type

İstemci, sunucunun anlamadığı bir gövde gönderdi. Yalnızca JSON kabul eden bir API’ye XML POST etmek 415 döner. Yanıt, kabul edilebilir tipleri ima etmelidir.

422 Unprocessable Content

İstek sorunsuz ayrıştırılır, ancak anlamsal doğrulamadan geçemez. RFC 9110, 2022’de bunu WebDAV’dan çekirdek spesifikasyona taşıdı. Doğrulama hataları için 422 kullanın:

{
  "error": "validation_failed",
  "details": [
    {"field": "email", "message": "must be a valid email"},
    {"field": "age", "message": "must be at least 13"}
  ]
}

API’niz 400 ile 422 arasında karar veremiyorsa kural şudur: “ben bunu ayrıştıramıyorum bile” için 400, “ayrıştırdım ama anlamlı değil” için 422.

425 Too Early

Sunucu, TLS 1.3 early-data tekrarı olabilecek bir isteği işleme riskini almak istemediğinde gönderilir. Çoğunlukla CDN’ler ve ters proxy’lerle ilgilidir.

428 Precondition Required

Sunucu, kayıp güncelleme problemini önlemek için If-Match veya If-Unmodified-Since göndermenizde ısrar eder. Ortak çalışmalı düzenleme API’lerinde kullanılır.

429 Too Many Requests

Hız sınırlandı. Yanıt, iyi davranan istemcilerin geri çekilebilmesi için Retry-After (saniye olarak veya HTTP tarihi olarak) içermek zorundadır.

HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/json

{"error": "rate_limited", "limit": 100, "window": "1m"}

Numara, Ray Bradbury’nin “Fahrenheit 451” romanına bir göndermedir, ama kullanım amacı kurgu değildir: DMCA kaldırmaları, GDPR unutulma hakkı talepleri ve ülke düzeyinde coğrafi engellerin tümü 451’i haklı çıkarır. Yanıt, RFC 7725 uyarınca engeli zorunlu kılan yasal otoriteyi işaret eden bir Link header’ı içermelidir.

418 I’m a Teapot (paskalya yumurtası)

Gerçek bir kod. RFC 2324 (1 Nisan 1998 şakası) ve IETF, fazla sayıda ürün şaka olsun diye uyguladığı için bunu kayıtlardan çıkarmadı. Gerçek bir API’de 418 göndermeyin; çoğu ters proxy ve yük dengeleyici onu yanlış işler.

Karar matrisi: hangi 4xx?

DurumKod
Gövde hatalı veya ayrıştırılamıyor400
Kimlik doğrulama yok / token süresi dolmuş401
Kimlik doğrulandı ama izin yok403
URL yok (veya saklıyorsunuz)404
URL vardı, kasten kaldırıldı410
Yanlış HTTP method’u405 (Allow ile)
Yanlış Content-Type415
İyimser kilit çakışması409
Doğrulama hatası (ayrıştırılır, doğrulanmaz)422
Hız sınırlandı429 (Retry-After ile)
Yasal nedenlerle engellendi451

5xx — server errors (gerçekte bozulan ne)

5xx “hata bizde” demektir. Nöbetteki mühendisleri en çok ilgilendiren, sabah 3’te onları uyandıran 5xx’tir; çünkü kod, önce hangi katmanı incelemeniz gerektiğini söyler.

500 Internal Server Error

Tüm yakalayıcı. Neredeyse her zaman, framework’ün varsayılan handler’ına kadar yükselen yakalanmamış bir istisnadır. Size sebep hakkında hiçbir şey söylemez; burada yapılandırılmış log’lamanın durum kodundan daha önemli olmasının nedeni budur.

501 Not Implemented

Sunucu method’u hiç desteklemiyor. 405’ten farklıdır (bu method bu URL için izinli değil); 501 “bu sunucunun PROPFIND’ın ne demek olduğu hakkında hiçbir fikri yok” demektir. REST API’lerinde nadir.

502 Bad Gateway

Bir ters proxy veya yük dengeleyici, yukarı akıştan geçersiz bir yanıt aldı. Yukarı akış cevap verdi ama çöp şeklinde: yanlış protokol, hatalı header’lar, yanıt ortasında düşen bağlantı. CDN’inizden 502 görüyorsanız, origin muhtemelen çöküyor veya kesilmiş gövdeler döndürüyordur.

503 Service Unavailable

Sunucu şu anda kasıtlı olarak istek karşılamıyor. Bunu bakım pencereleri veya zarif aşırı yük yanıtları için kullanın. Retry-After içermelidir.

504 Gateway Timeout

Ters proxy yukarı akışı bekledi ve yukarı akış zamanında hiç yanıt vermedi. Yukarı akış yavaş veya takılı; yukarı akışın çöple yanıt verdiği 502’den farklıdır.

502 vs 504: nöbet teşhisi

Gördüğünüzİlk kontrol edilecek şey
502 Bad GatewayYukarı akış geçersiz veriyle yanıtlıyor; origin log’larını çökmeler, hatalı yanıtlar, protokol uyumsuzlukları için kontrol edin
504 Gateway TimeoutYukarı akış asılı; origin CPU’sunu, DB sorgularını, aşağı akış API çağrılarını ve proxy’nin proxy_read_timeout ayarını kontrol edin

Yaygın bir karışıklık: 60 saniye süren bir veritabanı sorgusu, proxy’niz 30 saniyede zaman aşımına uğruyorsa 504, uygulama sunucusu 90 saniyede zaman aşımına uğrayıp istisna fırlatıyorsa 500 olarak yüzeye çıkar. Aynı kök neden, farklı kod, farklı log satırı; panolarınızı her ikisini de yüzeye çıkaracak şekilde eğitin.

507 Insufficient Storage

WebDAV’a özgü. Sunucuda disk dolu. Bunu WebDAV olmayan bir API’den görüyorsanız, biri anlamı çarpıtıyor demektir.

508 Loop Detected

WebDAV PROPFIND operasyonlarında sonsuz özyineleme. Çok nadir.

511 Network Authentication Required

Captive portal kodu: bir otel veya havalimanındaki WiFi, tarayıcınıza “önce portalda giriş yapmanız gerekiyor” demek için 511 gönderir. Yanıt, portal sayfasına bir Location içerir.

Sorun giderme matrisi: önce hangi katman kontrol edilir

KodAppProxyDBNetwork
500EvetBelki (yakalanmamış DB hatası)
502Evet (yukarı akış hatalı)Belki (TCP reset)
503Evet (bakım bayrağı)Evet (rate-limit reddi)
504Evet (yavaş handler)Evet (timeout konfigürasyonu)Evet (yavaş sorgu)Evet (DNS, paket kaybı)

Yaygın HTTP durum kodu anti-desenleri

Bu beş hata, üretimde gördüğümüz kötü kodun çoğunu açıklar.

1. Hataları 200 OK ile sarmak

HTTP/1.1 200 OK
{"success": false, "error": "user_not_found"}

Her izleme aracı, CDN ve önbellek artık isteğin başarılı olduğunu sanıyor. Yeniden deneme mantığı çuvallar. Durum kodu farkındalıklı yük dengeleyiciler kötü trafiği “sağlıklı” backend’lere yönlendirir. Bu desen JSON-RPC’den geldi ve GraphQL tarafından devralındı; GraphQL bunu yapıyor, çünkü kısmi başarılar alan başına hata raporlama gerektiriyor, bu adil. REST’in böyle bir mazereti yok: istemci hataları için 4xx, sunucu hataları için 5xx kullanın ve yapılandırılmış ayrıntıyı gövdeye koyun.

2. 401 ile 403’ü karıştırmak

401 ve 403’ünüz tutarlı değilse, saldırganlar API’nizi araştırarak hangi kaynakların var olduğunu keşfedebilir. Bir politika seçin: ya “bunu göremezsin” için 404 döndürün (GitHub’ın özel depolar için yaklaşımı) ya da tutarlı şekilde 403 döndürün. Tutarsızlık bilgi sızdırır.

3. 403’ü 404’ün arkasına saklamak

Bazen doğru, çoğu zaman bir bug. GitHub’ın özel depolar için 404 döndürmesi bilinçli; deponun varlığı başlı başına hassas. Ancak API’niz “bu kullanıcı hesabı askıya alındı” için 404 döndürürse, meşru kullanıcılar artık kullanıcı adını yanlış mı yazdıklarını yoksa askıya mı alındıklarını anlayamaz. Politikanızı açıkça belgeleyin ve tutarlı şekilde uygulayın.

4. 500’ü varsayılan yakalayıcı olarak kullanmak

Framework’ler bunu kolaylaştırıyor, sorun da burada. Yakalanmamış her istisna 500’e dönüşür ve uyarı sisteminiz “veritabanı çöktü” ile “kullanıcı hatalı bir UUID gönderdi” arasındaki farkı ayırt edemez. Doğrulama hatalarını yakalayıp 400 veya 422 fırlatın. ORM’inizden gelen NotFound’u yakalayıp 404 fırlatın. 500’ü gerçekten beklenmeyen başarısızlıklara saklayın; fırlattığınızda da ilişkilendirebilmek için bir request ID log’layın.

5. Uzun yönlendirme zincirleri

Her sıçrama bir round trip’e mal olur. /old/intermediate/canonical durumunda, bu en kötü durumda iki ek DNS aramasına ve iki ek TCP el sıkışmasına denk gelir. Google, 3 sıçramadan uzun zincirler için tarama önceliğini düşürür ve tarayıcılar döngüleri önlemek için yönlendirme zincirlerini yaklaşık 20 ile sınırlandırır. Zincirleri kaynağında daraltın: CDN konfigürasyonunuzda veya uygulamanızın yönlendirme haritasında.

HTTP durum kodları ve SEO

Arama motorları durum kodlarını, bir URL’yi tutmak, düşürmek veya aktarmak konusunda yetkili sinyaller olarak değerlendirir. Yanlış seçin, sıralamanız değişir.

301 Moved Permanently PageRank’i aktarır: Google, eskiyi işaret eden tüm sinyallerin yeni URL’yi kanonik hedef olarak kabul eder. 302 Found link gücünü aktarmaz (veya Google’ın sezgilerine bağlı olarak yavaş aktarır). Bir URL’yi sonsuza kadar yeniden adlandırdıysanız 301 kullanın. Bir konuğu /login’e yönlendiriyorsanız 302 kullanın.

404 vs 410 vs Soft 404

Google üç “eksik” durumu birbirinden ayırır:

  • 404 Not Found: Google düzenli olarak yeniden kontrol eder ve URL’yi bir süre indekste tutar.
  • 410 Gone: Google URL’yi çok daha hızlı düşürür, çoğunlukla tek bir tarama döngüsü içinde.
  • Soft 404: Google’ın 200 OK döndüren ama “bulunamadı” mesajı görüntüleyen sayfalar için kullandığı terim. Google bunu içerik desenlerinden tespit eder ve yine de 404 gibi davranır, ama siz bir tarama isteğini boşa harcamış ve muhtemelen gerçek içeriğinizi sulandırmış olursunuz.

Bayatlamış bir indeksi temizliyorsanız, kalıcı olarak kaldırılan URL’ler için gerçek 410’lar döndürün.

5xx ve tarama bütçesi

Google’ın tarayıcısı, bir site sürekli 5xx döndürdüğünde hızını düşürür. Search Console’un Crawl Stats raporu bunu gösterir: uzun süreli 5xx hata artışı tarama bütçenizi günlerce düşürebilir, bu da yeni sayfaların indekslenmesinin uzun sürmesi anlamına gelir. 5xx oranlarına yalnızca güvenilirlik metriği olarak değil, SEO metriği olarak da bakın.

Aslında bozuk olan 200 OK

Bir hata sayfasıyla 200 OK döndürmek (soft-404 anti-deseni) SEO için en kötü durumdur. Google hata mesajını indeksler, hiçbir şey için sıralar ve yavaş yavaş sayfanın bozuk olduğunu anlar. Tek sayfa uygulamanız özenli bir hata UI’sı render etse bile, daima sunucudan doğru durum kodunu döndürün.

HTTP durum kodları nasıl incelenir (araçlar)

Göremediğiniz şeyi düzeltemezsiniz. Çalışan her geliştirici bunlardan en az üçünde akıcı olmalı.

Tarayıcı DevTools Network paneli

Chrome, Firefox ve Safari’nin hepsi Network sekmesinde bir Status sütunu gösterir. Görünmüyorsa, sütun başlığına sağ tıklayıp Status Text’i ekleyin. Faydalı ipuçları:

  • Preserve log: gezintiler arasında girdileri tutarak tüm yönlendirme zincirini görmenizi sağlar.
  • Filter by status: yalnızca sunucu hatalarını görmek için status-code:5xx (Chrome) yazın.
  • Replay XHR: herhangi bir isteğe sağ tıklayın → Replay XHR ile sayfayı yeniden yüklemeden tekrar çalıştırın.

Yönlendirmeler için, her sıçramayı ve her adımdaki durum kodunu görmek üzere isteği genişletin.

curl (evrensel cevap)

curl her şeyi gösterir. Hata ayıklamanın büyük kısmını çözen üç desen:

# Just the status code
curl -o /dev/null -s -w "%{http_code}\n" https://api.example.com/users/1

# Headers only (HEAD request, follow redirects)
curl -I -L https://example.com

# Full verbose with request and response headers
curl -v https://api.example.com/users/1

Query string’lerde özel karakterler içeren test URL’leri oluştururken, kodlamayı curl’ün halletmesi için --data-urlencode kullanın ya da kabloya hangi baytların gerçekten gideceğini doğrulamak üzere URL’yi URL kodlayıcı ve çözücü aracımıza yapıştırın.

# curl encodes the query value for you
curl -G "https://api.example.com/search" \
  --data-urlencode "q=hello world & friends"

# Sends: GET /search?q=hello%20world%20%26%20friends

JavaScript fetch

Response.status özelliği tam sayı kodu içerir. Response.ok, herhangi bir 2xx için true olur.

const res = await fetch('https://api.example.com/users/1');

console.log(res.status);      // 200
console.log(res.statusText);  // "OK"
console.log(res.ok);          // true

if (!res.ok) {
  if (res.status === 401) {
    // refresh token and retry
  } else if (res.status === 429) {
    const retryAfter = Number(res.headers.get('Retry-After')) || 1;
    await new Promise(r => setTimeout(r, retryAfter * 1000));
  } else if (res.status >= 500) {
    throw new Error(`Server error: ${res.status}`);
  }
}

axios’ta aynı mantık interceptor’larda yaşar:

import axios from 'axios';

axios.interceptors.response.use(
  response => response,
  error => {
    const status = error.response?.status;
    if (status === 401) {
      // redirect to login
    }
    return Promise.reject(error);
  }
);

Python requests

import requests

r = requests.get('https://api.example.com/users/1')

print(r.status_code)  # 200
print(r.reason)       # 'OK'

# Raises requests.exceptions.HTTPError for 4xx/5xx
r.raise_for_status()

# Manual handling
if r.status_code == 429:
    retry_after = int(r.headers.get('Retry-After', '1'))
    time.sleep(retry_after)
elif 500 <= r.status_code < 600:
    raise RuntimeError(f'Server error: {r.status_code}')

raise_for_status(), “4xx/5xx’te yüksek sesle başarısız ol” için Python deyimidir. status_code üzerinde dallanmak yerine hatalarda istisna istediğiniz betiklerde kullanın.

Postman ve Bruno

Her ikisi de bir test betiğinin içinde durum kodları üzerinde assert yapmanıza izin verir:

// Postman/Bruno test script
pm.test("Status is 201", () => {
  pm.response.to.have.status(201);
});

pm.test("Has Location header", () => {
  pm.expect(pm.response.headers.get('Location')).to.match(/^\/users\/\d+$/);
});

Sözleşme ihlallerini canlıya çıkmadan yakalamak için bunları CI’da staging’e karşı çalıştırın.

SSS

401 ile 403 arasındaki fark nedir?

401 Unauthorized, sunucunun kim olduğunuzu bilmediği anlamına gelir; kimlik bilgileriniz eksik, süresi dolmuş veya geçersizdir. 403 Forbidden, sunucunun kim olduğunuzu bildiği ama yine de reddettiği anlamına gelir. Farklı kimlik bilgileri göndermek sorunu çözebilirse 401 kullanın. Çözmeyecekse 403 kullanın.

301’i mi 302’yi mi ne zaman kullanmalıyım?

Taşınma kalıcıysa 301 kullanın: eski URL bir daha gelmeyecek ve link gücünü arama motorlarının yeni URL’ye aktarmasını istiyorsunuz. Orijinal URL’nin hâlâ kanonik olduğu geçici yönlendirmeler (giriş akışları, A/B testi, bakım sayfaları) için 302 kullanın. API’ler için, istek method’unu koruduğu için 308 ve 307’yi tercih edin.

502 Bad Gateway hatası ne anlama gelir?

502, bir ters proxy veya yük dengeleyicinin yukarı akış sunucudan geçersiz bir yanıt aldığı anlamına gelir. Yukarı akış cevap verdi ama çöp şeklinde: yanlış protokol, hatalı header’lar veya düşen bir bağlantı. Yukarı akışın hiç yanıt vermediği 504 Gateway Timeout’tan farklıdır. İlk bakılacak yer: çökmeler veya kesilmiş yanıtlar için origin sunucu log’ları.

”Soft 404” nedir?

“Soft 404”, 200 OK döndüren ama aslında “bulunamadı” mesajı gösteren bir sayfadır. Google bunları sezgisel olarak tespit eder ve yine de 404 gibi davranır. Tarama bütçesini boşa harcar ve gerçek içeriğinizi sulandırabilirler. Tek sayfa uygulamanız özenli bir hata UI’sı render etse bile, daima sunucudan gerçek 404 veya 410 durum kodları döndürün.

400 yerine 422’yi ne zaman kullanmalıyım?

400 Bad Request kullanımı: sunucu isteği ayrıştıramıyorsa, yani hatalı JSON, eksik yapısal alanlar, söz dizimi hataları varsa. 422 Unprocessable Content kullanımı: istek sorunsuz ayrıştırılıyor ama iş doğrulamasından geçmiyorsa, yani geçersiz e-posta biçimi, aralık dışı değer, anlamsal olarak tutarsız alanlar varsa. Kısacası: söz dizimi için 400, anlam için 422.

429 Too Many Requests’e nasıl yanıt vermeliyim?

Retry-After header’ını okuyun (saniye sayısı veya HTTP tarihi) ve yeniden denemeden önce en az o kadar geri çekilin. Retry-After eksikse, 1 saniye civarında başlayıp jitter’lı üstel geri çekilme kullanın. Asla anında yeniden denemeyin; banlanma yöntemi tam da budur.

1xx informational kodları 2026’da hâlâ kullanılıyor mu?

Evet, ama çoğu uygulama kodu için görünmezdir. 100 Continue ve 101 Switching Protocols, temel HTTP/1.1 özellikleridir. 103 Early Hints, asıl yanıttan önce preload ipuçları iletmek için Cloudflare, Fastly ve Vercel tarafından giderek daha çok kullanılıyor; Largest Contentful Paint’i ölçülebilir biçimde iyileştiriyor. Çoğu HTTP kütüphanesi 1xx’i nihai yanıta katlar, dolayısıyla bunları genellikle yalnızca DevTools’ta veya curl -v ile görürsünüz.

418 “I’m a teapot” gerçek bir durum kodu mu?

Evet. RFC 2324, 1998’den kalma bir 1 Nisan şakasıydı, ama yeterince ürün bunu uyguladığı için IETF onu RFC 7168’de kayıtlarda tuttu. 418’i canlıda göndermeyin; birçok ters proxy ve yük dengeleyici bunu doğru işlemez ve şaka dışında gerçek bir amaca hizmet etmez.