Skip to content
Zurück zum Blog
Tutorials

HTTP-Statuscodes Spickzettel: 1xx bis 5xx erklärt

Vollständige HTTP-Statuscode-Referenz von 1xx bis 5xx mit Beispielen, typischen Fehlern (401 vs 403, 301 vs 302) und SEO-Wirkung. Spickzettel ansehen.

14 Min. Lesezeit

HTTP-Statuscodes Spickzettel: 1xx bis 5xx erklärt

Sie öffnen die DevTools, und der Network-Tab leuchtet halb rot. Ihr Endpoint liefert in Produktion 502, lokal 200, und ein Kollege fragt gerade in Slack: „Ist das ein 401 oder ein 403?” HTTP-Statuscodes wirken simpel (drei Ziffern, fünf Klassen), doch eine falsche Wahl gibt Informationen preis, ruiniert Ihr SEO und macht jede On-Call-Schicht zur Tortur.

Dieser Leitfaden ist ein vollständiger HTTP-Statuscode-Spickzettel für die tägliche Entwicklungsarbeit. Sie bekommen drei Dinge: (1) eine Schnellreferenztabelle aller Codes, denen Sie tatsächlich in der Praxis begegnen, (2) Entscheidungsmatrizen für die Paare, die regelmäßig verwechselt werden (301 vs 302, 401 vs 403, 404 vs 410, 502 vs 504), und (3) einen Tooling-Abschnitt, der zeigt, wie Sie Statuscodes mit curl, fetch und Python requests inspizieren. Jeder Code unten beruht auf RFC 9110, dem aktuellen Standard für HTTP-Semantik, und auf der IANA HTTP Status Code Registry.

Schnellreferenz: Alle HTTP-Statuscodes auf einen Blick

Hier sind die Codes, denen Sie in Produktion begegnen, gruppiert nach Klasse. Lesezeichen setzen; der Rest des Artikels erklärt die kniffligeren.

CodeNameWann Sie ihm begegnen
100ContinueGroßen POST-Body mit Expect: 100-continue senden
101Switching ProtocolsWebSocket-Handshake, HTTP/2-Upgrade
103Early HintsServer schickt Link-Header vor der eigentlichen Antwort
200OKStandard-Erfolg für GET, PUT, PATCH
201CreatedPOST, das eine Ressource anlegt (gibt Location zurück)
202AcceptedAsynchroner Job in der Warteschlange, Arbeit noch nicht erledigt
204No ContentDELETE-Erfolg, PUT ohne Antwort-Body
206Partial ContentRange-Request, Video-Seek, fortsetzbarer Download
301Moved PermanentlyAlte URL stillgelegt, Suchmaschinen übertragen Linkequity
302FoundTemporäre Weiterleitung, Original-URL bleibt kanonisch
303See OtherPost/Redirect/Get-Muster nach einem Formular-POST
304Not ModifiedBedingter GET mit passendem ETag oder If-Modified-Since
307Temporary RedirectWie 302, aber Methode und Body bleiben erhalten
308Permanent RedirectWie 301, aber Methode und Body bleiben erhalten
400Bad RequestFehlerhaftes JSON, fehlendes Pflichtfeld, Schema-Fehler
401UnauthorizedKeine Anmeldedaten oder abgelaufener Token
403ForbiddenAuthentifiziert, aber nicht berechtigt
404Not FoundRessource existiert nicht (oder Sie verbergen sie)
405Method Not AllowedPOST auf einen GET-only-Endpoint (muss Allow enthalten)
408Request TimeoutClient hat zu lange gebraucht, um die Anfrage zu senden
409ConflictOptimistic-Lock-Fehler, doppelter Schlüssel
410GoneRessource dauerhaft gelöscht, kommt nicht zurück
415Unsupported Media TypeFalscher Content-Type, z. B. XML an eine JSON-API
422Unprocessable ContentSyntax gültig, Semantik ungültig (Validierungsfehler)
425Too EarlyReplay-Risiko bei TLS-1.3-Early-Data
428Precondition RequiredServer verlangt If-Match, um verlorene Updates zu vermeiden
429Too Many RequestsRate-Limit (muss Retry-After enthalten)
451Unavailable for Legal ReasonsDMCA, DSGVO-Sperrung, Geo-Block
500Internal Server ErrorUnbehandelte Exception in Ihrem Code
501Not ImplementedMethode oder Feature nicht unterstützt (in REST selten)
502Bad GatewayUpstream lieferte eine ungültige Antwort
503Service UnavailableWartungsmodus oder Überlast
504Gateway TimeoutUpstream hat nicht rechtzeitig geantwortet
507Insufficient StorageWebDAV: Speicherplatz erschöpft
508Loop DetectedEndlose Weiterleitung oder Rekursion in WebDAV
511Network Authentication RequiredCaptive Portal in Hotel- oder Flughafen-WLAN

Der Rest des Artikels erläutert jede Klasse mit Entscheidungsmatrizen, Anti-Patterns und den SEO-Folgen falscher Codewahl.

Wie HTTP-Statuscodes funktionieren (Anatomie der drei Ziffern)

Warum drei Ziffern?

HTTP-Statuscodes sind dreistellige Dezimalzahlen, weil HTTP/0.9 ein Signal mit fester Breite brauchte: klein genug, damit ein Parser schnell darauf verzweigen kann, und groß genug, um Platz für neue Codes zu lassen. Drei Ziffern ergeben 900 mögliche Werte (100–999), mehr als genug; das IANA-Register nutzt heute nur etwa 60 davon.

Die erste Ziffer bezeichnet die Klasse. Die zweite und dritte stehen für den konkreten Code innerhalb dieser Klasse. Ein Client, der 418 nicht kennt, sollte ihn wie einen generischen 4xx behandeln. RFC 9110 §15 macht das explizit: Clients müssen unbekannte Codes wie das x00 ihrer Klasse behandeln.

Die fünf Klassen im Überblick

KlasseBedeutungBody erforderlich?Standardmäßig cachebar?
1xxInformation — Zwischenstand, mehr folgtNeinNein
2xxErfolg — Anfrage verstanden und akzeptiertOftHängt von der Methode ab
3xxUmleitung — weitere Aktion nötigOptional301, 308 ja; 302, 307 nein
4xxClient-Fehler — Ihr Fehler, Anfrage korrigierenJa (erklären)In der Regel nein
5xxServer-Fehler — unser Fehler, Retry kann helfenJa (erklären)Nein

Die Spalte „standardmäßig cachebar” ist wichtig. CDNs und Browser cachen 301 und 308 aggressiv und auf Dauer; eine falsche Wahl in Produktion ist schwer rückgängig zu machen, weil Nutzer die Weiterleitung lokal gecacht haben. Darauf kommen wir im SEO-Abschnitt zurück.

Wer tiefer in die URL-Struktur einsteigen will (auf der die Redirect-Codes operieren), findet im Beitrag URL-Encoding und -Decoding eine Tour durch Percent-Encoding, Query-Strings und die Byte-Pipeline, die festlegt, was eine URL überhaupt gültig macht.

1xx — Informational (wann Sie sie wirklich sehen)

Die meisten Entwickler bekommen jahrelang keinen 1xx direkt zu Gesicht. Es sind Zwischenantworten, mit denen der Server dem Client signalisiert: „Ich bin noch da, mach weiter.” Browser-DevTools blenden sie meist aus, und die meisten HTTP-Bibliotheken fassen sie mit der finalen Antwort zusammen.

Für jeden Code unten ist MDNs Referenz zu HTTP-Antwortstatuscodes die freundlichste Querverweis-Quelle, falls Sie eine Definition gegenprüfen möchten.

100 Continue

Der Client sendet Expect: 100-continue in den Headern und wartet, bevor er einen großen Request-Body überträgt. Der Server antwortet 100 Continue, wenn er den Body annehmen will, oder mit einem 4xx, wenn er die Anfrage ohnehin ablehnt. Das spart Bandbreite bei großen Uploads. Keinen Sinn, 200 MB zu senden, wenn der Server wegen eines fehlenden Headers ablehnt.

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

Wenn Sie kein < HTTP/1.1 100 Continue in der Verbose-Ausgabe sehen, hat Ihr Client den Header vermutlich entfernt oder der Server unterstützt ihn nicht.

101 Switching Protocols

Der Handshake, der eine HTTP-Verbindung in eine WebSocket- oder HTTP/2-Verbindung verwandelt. Der Client sendet Upgrade: websocket, der Server antwortet mit 101 Switching Protocols, und ab da spricht die Verbindung ein anderes Protokoll. Sie sehen das im Network-Tab jeder Chat-App, jedes Live-Dashboards und jedes Kollaborationswerkzeugs.

103 Early Hints

Ein vergleichsweise junger Code (RFC 8297, 2017), mit dem der Server Link-Header für Preload-Hinweise senden kann, bevor die Hauptantwort fertig ist. Der Browser beginnt, CSS und JS zu laden, während der Server noch rendert. Stand 2026 unterstützen Cloudflare, Fastly und Vercel 103 in Produktion, die moderne Alternative zu HTTP/2 Server Push (das in Chrome eingestellt wurde).

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-Pattern-Check: Wenn Ihr Client nie 1xx-Codes sieht, obwohl Sie sie erwarten, liegt es meist an einem Reverse-Proxy. Ältere nginx-Versionen entfernen Expect: 100-continue und 103 Early Hints. Prüfen Sie die Proxy-Konfiguration, bevor Sie dem Server die Schuld geben.

2xx — Erfolg (mehr als nur 200)

Für alles 200 OK zurückzugeben, ist der häufigste Code-Smell in REST-APIs. Die 2xx-Familie trägt semantische Information, die Clients schlauer und Caches effizienter macht.

200 OK

Der Standardfall. Ein GET liefert die Ressource, ein PUT liefert die aktualisierte Ressource (oder 204), ein PATCH die gepatchte Ressource. Wenn es keinen Grund für einen spezifischeren Code gibt, nehmen Sie 200.

201 Created

Ein POST, der eine neue Ressource anlegt, sollte 201 plus einen Location-Header auf die neue Ressource zurückgeben. So entdecken RESTful-Clients die kanonische URL des soeben erzeugten Objekts.

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

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

202 Accepted

Der Server hat die Anfrage angenommen, aber die Verarbeitung noch nicht abgeschlossen. Verwenden Sie das für asynchrone Arbeit: Der Client soll pollen, einen Webhook abonnieren oder einen Status-Endpoint abfragen. Geben Sie eine Job-ID im Body mit.

204 No Content

Erfolg, kein Body. Üblich bei DELETE (die Ressource ist weg, was sollte man zurückgeben?) und bei PUT-Operationen, bei denen der Client den neuen Zustand bereits kennt. Browser wechseln nach einem Formular-Submit mit 204 nicht die Seite, praktisch für Fire-and-Forget-Aktionen in SPAs.

206 Partial Content

Antwort auf Range-Anfragen: Der Client hat per Range: bytes=1000-2000 die Bytes 1000–2000 angefordert, der Server liefert genau diesen Ausschnitt. Video-Streaming, fortsetzbare Downloads und HTTP-basierte Datei-Synchronisation hängen alle an 206.

Entscheidung: 200 vs 201 vs 204 für POST

SzenarioCodeBody
POST legt eine neue Ressource an201 CreatedNeue Ressource (oder nur ID) + Location
POST stößt asynchrone Arbeit an, Ergebnis noch offen202 AcceptedJob-ID, Poll-URL
POST ist eine Aktion ohne Ressource (z. B. /login)200 OKAktionsergebnis (Token, Status)
POST gelingt, aber die Antwort ist leer204 No Content(keiner)

Wenn Sie zwischen 200 und 201 schwanken, fragen Sie sich: „Hat der Server eine Ressource erzeugt, die jetzt eine eigene URL hat?” Wenn ja, 201. Wenn nein, 200.

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

Redirects sind die am häufigsten falsch eingesetzte Klasse. Die Unterschiede zwischen 301, 302, 307 und 308 ergeben sich aus drei voneinander unabhängigen Fragen: Ist die Verschiebung dauerhaft, bleibt die Methode erhalten und ist die Antwort cachebar?

301 Moved Permanently

Die Ressource ist umgezogen und kommt nicht zurück. Suchmaschinen übertragen die Linkequity an die neue URL. Browser und CDNs cachen 301 zeitlich unbegrenzt: Wenn Sie /old mit 301 auf /new umleiten und es sich später anders überlegen, gehen Nutzer mit gecachtem Redirect für immer auf /new (oder bis sie ihren Cache leeren).

Historisch konnten Browser bei einem 301 die Methode umschreiben (POST → GET); deshalb hat HTTP/1.1 308 eingeführt, um genau das zu beheben.

302 Found

Temporäre Weiterleitung. Die Original-URL bleibt kanonisch, Suchmaschinen sollen weiterhin das Original indexieren. Verwenden Sie das für A/B-Test-Routing, Wartungsseiten oder „bitte einloggen, um fortzufahren”-Flows.

Wie bei 301 haben Browser historisch POST zu GET umgeschrieben. Wenn Sie einen POST umleiten und ihn als POST behalten wollen, nehmen Sie stattdessen 307.

303 See Other

Schreibt die Methode immer auf GET um. Das Post/Redirect/Get-Muster: Formular sendet POST an /submit, der Server antwortet mit 303 und Location: /thank-you, der Browser ruft GET /thank-you auf. Aktualisiert man die Danke-Seite, wird das Formular nicht erneut gesendet. Genau dafür wurde 303 entworfen.

304 Not Modified

Die bedingte Antwort. Der Client schickt If-None-Match: "abc123" (oder If-Modified-Since), der Server prüft, ob sich die Ressource geändert hat, und antwortet wenn nicht mit 304 ohne Body. Der Browser nutzt seine zwischengespeicherte Kopie. Genau so halten CDNs und Caching-Schichten Ihre Seite schnell.

307 Temporary Redirect

Wie 302, aber die Methode darf sich nicht ändern. POST bleibt POST, der Body bleibt erhalten. Verwenden Sie das, wenn Sie eine temporäre Weiterleitung auf einer Nicht-GET-Anfrage brauchen.

308 Permanent Redirect

Wie 301, aber die Methode darf sich nicht ändern. Die moderne, sicherere Wahl für dauerhafte Weiterleitungen bei APIs, die POST/PUT akzeptieren.

Entscheidungsmatrix: welcher Redirect-Code?

Dauerhaft (für immer cachen)Temporär (nicht cachen)
Methode darf zu GET werden301 Moved Permanently302 Found
Methode muss gleich bleiben308 Permanent Redirect307 Temporary Redirect

Sonderfall: Wenn Sie ausdrücklich POST → GET wollen (das Post/Redirect/Get-Muster), nehmen Sie 303 See Other.

Bei HTML-Seiten mit Browser-Navigation sind 301 und 302 meist in Ordnung, weil GET ohnehin GET bleibt. Bei APIs und Formularen sind 308 und 307 vorzuziehen, um überraschende Methodenänderungen zu vermeiden.

4xx — Client-Fehler (den richtigen wählen)

4xx heißt: der Client hat etwas falsch gemacht. Je breiter Ihr 4xx-Vokabular, desto leichter ist Ihre API zu nutzen: Clients können auf den Code verzweigen, statt Fehler-Strings zu parsen.

400 Bad Request

Generischer Syntaxfehler. Fehlerhaftes JSON, ein strukturell fehlendes Pflichtfeld, eine Anfrage, die der Server nicht einmal parsen kann. Wenn die Anfrage parst, aber die fachliche Validierung fehlschlägt, nehmen Sie lieber 422.

401 Unauthorized vs 403 Forbidden

Das am häufigsten verwechselte Paar in HTTP. Die Trennlinie ist einfach, sobald man sie kennt:

  • 401 Unauthorized: der Anfrage fehlt eine gültige Authentifizierung. Der Server weiß nicht, wer Sie sind. Anmeldedaten erneut zu senden (oder den Token zu erneuern) kann das Problem lösen. Die Antwort muss laut RFC 9110 §15.5.2 einen WWW-Authenticate-Header enthalten.
  • 403 Forbidden: der Server weiß, wer Sie sind, und verweigert trotzdem. Ein erneutes Senden der Anfrage hilft nicht. Sie brauchen andere Anmeldedaten oder andere Berechtigungen.
Sie sehenWas das heißt
401 mit WWW-Authenticate: BearerKein Token, abgelaufener Token oder ungültiger Token
403 nach erfolgreichem LoginEingeloggt, aber dieser Nutzer darf nicht auf diese Ressource
401 nach erfolgreichem LoginBug, vermutlich wollten Sie 403

Anti-Pattern: 403-als-404. Manche Sites antworten mit 403, wenn ein nicht angemeldeter Nutzer /admin/dashboard anfragt. Das verrät die Existenz von /admin/dashboard. GitHub löst das, indem es für private Repositories, in denen man kein Mitglied ist, 404 liefert: die Ressource „existiert nicht” aus Ihrer Sicht. Das ist eine bewusste Entscheidung zum Verbergen von Information, kein Bug.

404 Not Found vs 410 Gone

Beide sagen „diese Ressource ist nicht da.” Der Unterschied liegt in Dauerhaftigkeit und SEO.

  • 404 Not Found: könnte existieren, könnte nicht, könnte zurückkommen. Suchmaschinen prüfen weiter.
  • 410 Gone: war hier, wurde absichtlich entfernt, kommt nicht zurück. Suchmaschinen entfernen die URL deutlich schneller aus dem Index.

Wenn Sie eine Produktseite löschen und sie sofort aus Googles Index haben wollen, ist 410 die richtige Wahl. Wenn eine URL nur vorübergehend kaputt ist, reicht 404.

405 Method Not Allowed

Die URL existiert, akzeptiert diese Methode aber nicht. Die Antwort muss einen Allow-Header mit den unterstützten Methoden enthalten.

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

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

Den Allow-Header zu vergessen ist die häufigste Vertragsverletzung in handgestrickten REST-APIs.

408 Request Timeout

Der Client hat begonnen, eine Anfrage zu senden, und ist dann verstummt. Der Server hat aufgegeben. Anders als 504 Gateway Timeout, der den Upstream betrifft, heißt 408: „Sie, der Client, haben zu lange gebraucht.”

409 Conflict

Die Anfrage steht im Konflikt mit dem aktuellen Zustand. Häufigster Einsatz: Optimistic Locking. Der Client schickt If-Match: "etag-v3", der aktuelle ETag des Servers ist "etag-v4", also wird das Update mit 409 abgelehnt.

410 Gone

Siehe oben: dauerhaftes Löschen. Nützlich, um soft-gelöschte Datensätze aus Suchindizes zu entfernen.

415 Unsupported Media Type

Der Client hat einen Body geschickt, den der Server nicht versteht. XML an eine reine JSON-API zu posten, gibt 415. Die Antwort sollte auf akzeptierte Typen hinweisen.

422 Unprocessable Content

Die Anfrage parst sauber, scheitert aber an der semantischen Validierung. RFC 9110 hat den Code 2022 endlich von WebDAV in den Kernstandard übernommen. Verwenden Sie 422 für Validierungsfehler:

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

Wenn Ihre API zwischen 400 und 422 schwankt, gilt die Faustregel: 400 für „ich kann das nicht einmal parsen”, 422 für „ich habe es geparst, und es ergibt keinen Sinn”.

425 Too Early

Wird gesendet, wenn der Server das Risiko vermeiden will, einen Request zu verarbeiten, der ein Replay von TLS-1.3-Early-Data sein könnte. Vor allem für CDNs und Reverse-Proxies relevant.

428 Precondition Required

Der Server besteht darauf, dass Sie If-Match oder If-Unmodified-Since mitschicken, um das Lost-Update-Problem zu vermeiden. Wird in APIs für kollaboratives Editieren genutzt.

429 Too Many Requests

Rate-Limit. Die Antwort muss Retry-After enthalten (in Sekunden oder als HTTP-Datum), damit sich anständige Clients zurücknehmen können.

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

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

Die Zahl ist eine Anspielung auf Bradbury. Der Anwendungsfall ist nicht fiktional: DMCA-Takedowns, DSGVO-Löschanfragen und länderbezogene Geo-Blocks rechtfertigen 451. Die Antwort sollte laut RFC 7725 einen Link-Header auf die rechtliche Instanz enthalten, die die Sperre verlangt.

418 I’m a Teapot (das Easter Egg)

Ja, den gibt es wirklich. RFC 2324 (Aprilscherz von 1998), und die IETF hat ihn behalten, weil zu viele Produkte ihn aus Spaß implementiert haben. Setzen Sie 418 nicht in einer echten API ein: Die meisten Reverse-Proxies und Load-Balancer kommen damit nicht richtig zurecht.

Entscheidungsmatrix: welcher 4xx?

SituationCode
Body fehlerhaft oder nicht parsbar400
Keine Authentifizierung / abgelaufener Token401
Authentifiziert, aber nicht erlaubt403
URL existiert nicht (oder Sie verbergen sie)404
URL existierte, absichtlich entfernt410
Falsche HTTP-Methode405 (mit Allow)
Falscher Content-Type415
Optimistic-Lock-Konflikt409
Validierungsfehler (parst, validiert nicht)422
Rate-Limit429 (mit Retry-After)
Aus rechtlichen Gründen gesperrt451

5xx — Server-Fehler (was wirklich kaputt ist)

5xx heißt: „unser Fehler.” On-Call-Engineers interessiert vor allem, welcher 5xx sie um drei Uhr nachts geweckt hat, denn der Code zeigt, in welcher Schicht Sie zuerst suchen sollten.

500 Internal Server Error

Der Sammelbegriff. Bedeutet fast immer, dass eine unbehandelte Exception bis zum Default-Handler des Frameworks durchgereicht wurde. Der Code sagt nichts über die Ursache, deshalb zählt strukturierte Logging-Ausgabe hier mehr als der Statuscode.

501 Not Implemented

Der Server unterstützt die Methode überhaupt nicht. Anders als 405 (diese Methode ist für diese URL nicht erlaubt) heißt 501: „Dieser Server hat keine Ahnung, was PROPFIND überhaupt bedeutet.” In REST-APIs selten.

502 Bad Gateway

Ein Reverse-Proxy oder Load-Balancer hat eine ungültige Antwort vom Upstream erhalten. Der Upstream hat geantwortet, aber mit Schrott: falsches Protokoll, fehlerhafte Header, mitten in der Antwort abgebrochene Verbindung. Sehen Sie 502 von Ihrem CDN, stürzt vermutlich der Origin ab oder liefert abgeschnittene Bodies.

503 Service Unavailable

Der Server bedient bewusst gerade keine Anfragen. Verwenden Sie das für Wartungsfenster oder graceful Antworten bei Überlast. Sollte Retry-After enthalten.

504 Gateway Timeout

Der Reverse-Proxy hat auf den Upstream gewartet, und der Upstream hat nicht rechtzeitig geantwortet. Der Upstream ist langsam oder hängt, anders als bei 502, wo der Upstream mit Schrott antwortet.

502 vs 504: die On-Call-Diagnose

Sie sehenWas Sie zuerst prüfen
502 Bad GatewayUpstream antwortet mit ungültigen Daten: Origin-Logs auf Crashes, fehlerhafte Antworten, Protokoll-Mismatches prüfen
504 Gateway TimeoutUpstream hängt: Origin-CPU, DB-Queries, ausgehende API-Calls und das proxy_read_timeout des Proxys prüfen

Häufige Verwechslung: Eine DB-Query, die 60 Sekunden dauert, taucht als 504 auf, wenn Ihr Proxy nach 30 Sekunden abbricht, aber als 500, wenn der App-Server nach 90 Sekunden eine Exception wirft. Gleiche Ursache, anderer Code, andere Logzeile. Trainieren Sie Ihre Dashboards darauf, beides sichtbar zu machen.

507 Insufficient Storage

WebDAV-spezifisch. Der Server hat keinen Plattenplatz mehr. Sehen Sie das von einer Nicht-WebDAV-API, biegt jemand die Bedeutung zurecht.

508 Loop Detected

Endlose Rekursion in WebDAV-PROPFIND-Operationen. Sehr selten.

511 Network Authentication Required

Der Captive-Portal-Code: Das WLAN im Hotel oder am Flughafen schickt 511, um Ihrem Browser zu sagen: „Sie müssen sich erst am Portal einloggen.” Die Antwort enthält ein Location zur Portalseite.

Troubleshooting-Matrix: welche Schicht zuerst prüfen

CodeAppProxyDBNetzwerk
500JaVielleicht (unbehandelter DB-Fehler)
502Ja (Upstream fehlerhaft)Vielleicht (TCP-Reset)
503Ja (Wartungsflag)Ja (Rate-Limit-Ablehnung)
504Ja (langsamer Handler)Ja (Timeout-Konfiguration)Ja (langsame Query)Ja (DNS, Paketverlust)

Häufige Anti-Patterns bei HTTP-Statuscodes

Diese fünf Fehler machen den Großteil des schlechten Codes aus, den ich review.

1. Fehler in 200 OK verpacken

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

Jetzt glaubt jedes Monitoring-Tool, jedes CDN und jeder Cache, die Anfrage sei erfolgreich gewesen. Retry-Logik funktioniert nicht mehr. Statuscode-bewusste Load-Balancer leiten kaputten Traffic auf „gesunde” Backends. Dieses Muster kommt aus JSON-RPC und wurde von GraphQL übernommen; bei GraphQL ist es vertretbar, weil Teil-Erfolge feldweise Fehlerinformationen brauchen. REST hat keine Ausrede: 4xx für Client-Fehler, 5xx für Server-Fehler, und die strukturierten Details in den Body.

2. 401 und 403 vermischen

Wenn Ihre 401 und 403 nicht konsistent sind, können Angreifer Ihre API systematisch abklopfen, um herauszufinden, welche Ressourcen existieren. Legen Sie eine Politik fest: Entweder geben Sie für „das dürfen Sie nicht sehen” 404 zurück (wie GitHub bei privaten Repos) oder konsistent 403. Inkonsistenz verrät Information.

3. 403 hinter 404 verstecken

Manchmal richtig, oft ein Bug. Dass GitHub für private Repos 404 liefert, ist Absicht: Die Existenz des Repos ist selbst sensibel. Wenn Ihre API aber 404 für „dieses Konto ist gesperrt” liefert, können legitime Nutzer nicht mehr unterscheiden, ob sie den Benutzernamen falsch geschrieben oder gesperrt wurden. Dokumentieren Sie Ihre Politik explizit und wenden Sie sie konsistent an.

4. 500 als Default-Catch nutzen

Frameworks machen das einfach, und genau das ist das Problem. Jede unbehandelte Exception wird zu 500, und Ihr Alerting kann „Datenbank ist down” nicht mehr von „Nutzer hat eine fehlerhafte UUID übergeben” unterscheiden. Fangen Sie Validierungsfehler ab und werfen Sie 400 oder 422. Fangen Sie NotFound aus Ihrem ORM ab und werfen Sie 404. Reservieren Sie 500 für wirklich unerwartete Fehler. Wenn Sie ihn werfen, loggen Sie eine Request-ID, damit Sie korrelieren können.

5. Lange Redirect-Ketten

Jeder Sprung kostet einen Roundtrip. Wenn /old/intermediate/canonical, sind das zwei zusätzliche DNS-Lookups und zwei zusätzliche TCP-Handshakes (im schlimmsten Fall). Google stuft das Crawl-Budget bei Ketten von mehr als drei Sprüngen herab, und Browser begrenzen Redirect-Ketten auf etwa 20, um Schleifen zu vermeiden. Lösen Sie Ketten an der Quelle auf, in der CDN-Konfiguration oder in der Redirect-Map Ihrer Anwendung.

HTTP-Statuscodes und SEO

Suchmaschinen behandeln Statuscodes als verbindliche Signale, ob eine URL behalten, verworfen oder übertragen werden soll. Falsch gesetzt, verschiebt sich Ihr Ranking.

301 vs 302 (Linkequity)

301 Moved Permanently überträgt PageRank: Google behandelt die neue URL als kanonisches Ziel aller Signale, die auf die alte zeigen. 302 Found überträgt keine Linkequity (oder nur langsam, abhängig von Googles Heuristiken). Wenn Sie eine URL dauerhaft umbenannt haben, nehmen Sie 301. Wenn Sie einen Gast nach /login schicken, nehmen Sie 302.

404 vs 410 vs Soft-404

Google unterscheidet drei „fehlt”-Zustände:

  • 404 Not Found: Google prüft regelmäßig nach und behält die URL eine Weile im Index.
  • 410 Gone: Google entfernt die URL schneller, oft schon im selben Crawl-Zyklus.
  • Soft-404: Googles Begriff für eine Seite, die 200 OK liefert, aber eine „nicht gefunden”-Meldung anzeigt. Google erkennt das anhand von Inhaltsmustern und behandelt es ohnehin als 404, doch Sie haben einen Crawl verschwendet und eventuell echten Inhalt verwässert.

Wenn Sie einen veralteten Index aufräumen, geben Sie für dauerhaft entfernte URLs echte 410 zurück.

5xx und Crawl-Budget

Googles Crawler reduziert seine Frequenz, wenn eine Site dauerhaft 5xx liefert. Der Crawl-Statistik-Bericht in der Search Console zeigt das. Eine anhaltende Welle von 5xx-Fehlern kann Ihr Crawl-Budget tagelang drücken, was bedeutet, dass neue Seiten länger zur Indexierung brauchen. Behandeln Sie 5xx-Raten als SEO-Metrik, nicht nur als Zuverlässigkeitsmetrik.

200 OK, das in Wahrheit kaputt ist

200 OK mit einer Fehlerseite zurückzugeben (das Soft-404-Anti-Pattern) ist der schlimmste Fall fürs SEO. Google indexiert die Fehlermeldung, rankt sie für nichts und merkt nur langsam, dass die Seite kaputt ist. Geben Sie immer den richtigen Statuscode vom Server zurück, auch wenn Ihre SPA eine freundliche Fehler-UI rendert.

Wie Sie HTTP-Statuscodes inspizieren (Tooling)

Was Sie nicht sehen, können Sie nicht beheben. Jeder Entwickler im Berufsalltag sollte mindestens drei der folgenden Werkzeuge fließend beherrschen.

Der Network-Panel der Browser-DevTools

Chrome, Firefox und Safari zeigen alle eine Status-Spalte im Network-Tab. Klicken Sie mit der rechten Maustaste auf die Spaltenüberschrift, um Status Text hinzuzufügen, falls er nicht zu sehen ist. Nützliche Tricks:

  • Preserve log: Einträge über Navigationen hinweg behalten, um die volle Redirect-Kette zu sehen.
  • Nach Status filtern: Tippen Sie status-code:5xx (Chrome), um nur Server-Fehler zu sehen.
  • Replay XHR: Rechtsklick auf einen Request → Replay XHR, um ihn ohne Reload erneut auszuführen.

Bei Redirects können Sie den Request aufklappen, um jeden Sprung mit Statuscode zu sehen.

curl (die universelle Antwort)

curl zeigt alles. Drei Muster, die 90 % aller Debugging-Fälle abdecken:

# 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

Wenn Sie Test-URLs mit Sonderzeichen in Query-Strings bauen, lassen Sie das Encoding mit --data-urlencode von curl erledigen oder fügen Sie die URL in unseren URL-Dekodierer & -Kodierer ein, um zu prüfen, welche Bytes tatsächlich auf die Leitung gehen.

# 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

Die Eigenschaft Response.status enthält den ganzzahligen Code. Response.ok ist true für jeden 2xx.

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}`);
  }
}

In axios lebt dieselbe Logik in den Interceptors:

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() ist die Python-Idiomatik für „bei 4xx/5xx laut scheitern”. Verwenden Sie es in Skripten, in denen Sie bei Fehlern Exceptions wollen, statt auf status_code zu verzweigen.

Postman und Bruno

Beide erlauben Assertions auf Statuscodes in einem Test-Skript:

// 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+$/);
});

Lassen Sie diese in CI gegen Staging laufen, um Vertragsverletzungen vor Produktion zu erwischen.

FAQ

Was ist der Unterschied zwischen 401 und 403?

401 Unauthorized heißt: Der Server weiß nicht, wer Sie sind, Ihre Anmeldedaten fehlen, sind abgelaufen oder ungültig. 403 Forbidden heißt: Der Server weiß, wer Sie sind, und verweigert trotzdem. Wenn andere Anmeldedaten das Problem lösen können, nehmen Sie 401. Wenn nicht, 403.

Wann sollte ich 301 statt 302 verwenden?

Nehmen Sie 301, wenn der Umzug dauerhaft ist: Die alte URL kommt nie zurück, und Suchmaschinen sollen Linkequity auf die neue URL übertragen. Nehmen Sie 302 für temporäre Weiterleitungen, bei denen die Original-URL kanonisch bleibt (Login-Flows, A/B-Tests, Wartungsseiten). Für APIs sind 308 und 307 vorzuziehen, weil sie die Anfrage-Methode erhalten.

Was bedeutet ein 502-Bad-Gateway-Fehler?

502 bedeutet, dass ein Reverse-Proxy oder Load-Balancer eine ungültige Antwort vom Upstream-Server bekommen hat. Der Upstream hat geantwortet, aber mit Schrott: falsches Protokoll, fehlerhafte Header oder eine abgebrochene Verbindung. Anders als 504 Gateway Timeout, wo der Upstream gar nicht geantwortet hat. Erste Anlaufstelle: die Logs des Origin-Servers auf Crashes oder abgeschnittene Antworten prüfen.

Was ist ein „Soft-404”?

Ein „Soft-404” ist eine Seite, die 200 OK liefert, aber tatsächlich eine „nicht gefunden”-Meldung anzeigt. Google erkennt das heuristisch und behandelt sie ohnehin als 404. Sie verschwenden Crawl-Budget und können echten Inhalt verwässern. Geben Sie immer echte 404- oder 410-Statuscodes vom Server zurück, auch wenn Ihre SPA eine freundliche Fehler-UI rendert.

Wann sollte ich 422 statt 400 verwenden?

Nehmen Sie 400 Bad Request, wenn der Server die Anfrage nicht einmal parsen kann: fehlerhaftes JSON, fehlende strukturelle Felder, Syntaxfehler. Nehmen Sie 422 Unprocessable Content, wenn die Anfrage sauber parst, aber an der fachlichen Validierung scheitert: ungültiges E-Mail-Format, Wert außerhalb des Bereichs, semantisch widersprüchliche Felder. Kurzformel: 400 für Syntax, 422 für Semantik.

Wie reagiere ich auf 429 Too Many Requests?

Lesen Sie den Retry-After-Header (eine Anzahl Sekunden oder ein HTTP-Datum) und warten Sie mindestens so lange, bevor Sie es erneut versuchen. Fehlt Retry-After, verwenden Sie exponentielles Backoff mit Jitter, beginnend bei etwa einer Sekunde. Niemals sofort wiederholen, sonst kassieren Sie eine Sperre.

Werden 1xx-Informationscodes 2026 noch verwendet?

Ja, doch die meisten sind für Anwendungs-Code unsichtbar. 100 Continue und 101 Switching Protocols sind Basis-Features von HTTP/1.1. 103 Early Hints wird zunehmend von Cloudflare, Fastly und Vercel genutzt, um Preload-Hinweise vor der Hauptantwort zu schicken; das verbessert spürbar den Largest Contentful Paint. Die meisten HTTP-Bibliotheken fassen 1xx mit der finalen Antwort zusammen, sodass Sie sie typischerweise nur in den DevTools oder bei curl -v sehen.

Ist 418 „I’m a Teapot” ein echter Statuscode?

Ja, erstaunlicherweise. RFC 2324 war ein Aprilscherz von 1998, doch genug Produkte haben ihn implementiert, sodass die IETF ihn in RFC 7168 stehen ließ. Setzen Sie 418 nicht in Produktion ein: Viele Reverse-Proxies und Load-Balancer kommen damit nicht zurecht, und außerhalb des Witzes hat er keinen Zweck.

Verwandte Artikel

Alle Artikel anzeigen