Ein Formular wird abgeschickt, aber im Frontend erscheint nur „Fehler“. In den DevTools steht „400“. Oder eine API antwortet mit „204“, obwohl eigentlich Daten erwartet werden. Solche Situationen kosten Zeit – oft nicht wegen des Bugs selbst, sondern weil der falsche Statuscode die Fehlersuche erschwert.
Dieser Artikel erklärt, wie HTTP-Statuscodes funktionieren, welche Codes im Alltag wirklich wichtig sind und wie sich Fehler in Webapps und APIs sauber abbilden lassen – ohne Raten, ohne Mythen, mit klaren Regeln.
Was ein Statuscode eigentlich sagt (und was nicht)
Ein HTTP-Statuscode ist eine Zahl, die der Server an den Client (Browser, App, API-Client) zurückgibt. Er beschreibt, wie der Server die Anfrage bewertet: erfolgreich, umgeleitet, fehlerhaft oder intern gescheitert.
Wichtig: Der Statuscode ist nicht „nur Kosmetik“. Er beeinflusst Caching, Monitoring, Retries (automatische Wiederholungen) und wie Tools Fehler einstufen.
Die groben Klassen: 2xx, 3xx, 4xx, 5xx
- 2xx Erfolg: Die Anfrage war ok. Nicht immer kommt Inhalt zurück.
- 3xx Umleitung: Die Ressource liegt woanders oder soll anders geladen werden.
- 4xx Client-Fehler: Die Anfrage war so nicht gültig (z. B. falsche Daten, keine Rechte).
- 5xx Server-Fehler: Die Anfrage war grundsätzlich ok, aber der Server konnte sie nicht verarbeiten.
Statuscode vs. Fehlermeldung: beides gehört zusammen
Ein Statuscode erklärt grob die Kategorie. Für Menschen und Frontends braucht es zusätzlich eine klare Fehlermeldung im Body (Antwortinhalt). Bei APIs ist üblich: eine kurze Message plus strukturierte Details (z. B. Feldfehler).
Erfolgscodes richtig einsetzen: 200 ist nicht immer passend
Viele Projekte nutzen „200 für alles“. Das wirkt bequem, macht aber Debugging und Client-Logik unnötig kompliziert. Besser ist: Erfolgscodes so wählen, dass sie das Ergebnis wirklich beschreiben.
200 OK, 201 Created und 204 No Content
- 200 OK: Standard, wenn eine Anfrage erfolgreich war und typischerweise Daten zurückkommen (z. B. GET /users).
- 201 Created: Wenn auf dem Server etwas neu angelegt wurde (z. B. POST /users). Idealerweise zeigt ein „Location“-Header auf die neue Ressource.
- 204 No Content: Wenn die Aktion erfolgreich war, aber bewusst kein Inhalt zurückkommt (z. B. DELETE oder ein Update ohne Response-Body).
Praxis-Tipp: Wenn ein Frontend nach einem POST direkt das neue Objekt anzeigen soll, ist 201 mit Response-Body oft sinnvoller als 204.
Typischer Stolperstein: 204 und trotzdem JSON senden
Bei 204 darf kein Body kommen. Einige Clients ignorieren ihn, andere werfen Fehler. Wenn Daten zurückkommen sollen, lieber 200 oder 201 nutzen.
Client-Fehler (4xx): nicht bestrafen, sondern erklären
4xx bedeutet: Der Client muss etwas ändern (Daten, Authentifizierung, Berechtigung, Pfad), damit die Anfrage klappt. Das ist ideal, um Probleme früh sichtbar zu machen.
400, 401, 403: ähnliche Wirkung, andere Bedeutung
| Status | Bedeutung | Typische Situation |
|---|---|---|
| 400 Bad Request | Anfrage ist syntaktisch/inhaltlich unbrauchbar | JSON kaputt, Pflichtfeld fehlt komplett, Parameter-Typ falsch |
| 401 Unauthorized | Keine gültige Authentifizierung | Token fehlt/abgelaufen; Login erforderlich |
| 403 Forbidden | Authentifiziert, aber nicht erlaubt | Rolle hat keine Rechte; Zugriff absichtlich blockiert |
Ein häufiger Fehler: 403 senden, wenn der Token fehlt. Das erschwert dem Client, korrekt zu reagieren (z. B. Login-Flow starten). Für Login-Themen sind Cookies und Sessions oft mitentscheidend.
404 Not Found vs. 410 Gone
404 ist der Klassiker: Ressource existiert nicht (oder der Server will es nicht verraten). 410 ist seltener, aber hilfreich, wenn etwas bewusst entfernt wurde und auch nicht wiederkommt (z. B. dauerhaft gelöschter Inhalt). In APIs reicht in der Praxis meist 404.
409 Conflict und 422 Unprocessable Entity
Wenn Daten zwar „lesbar“ sind, aber fachlich nicht passen, wird es spannend:
- 409 Conflict: Der Zustand kollidiert mit der aktuellen Situation. Beispiel: Benutzername soll gesetzt werden, ist aber schon vergeben; oder eine Optimistic-Locking-Version passt nicht mehr.
- 422 Unprocessable Entity: Validierung schlägt fehl, obwohl die Anfrage formal korrekt ist. Beispiel: E-Mail hat falsches Format, Passwort zu kurz, Datum liegt in der Vergangenheit.
Beide Codes sind nützlich, wenn die API klare Feldfehler liefert. Dazu passt auch das Thema Input-Validierung im Backend, weil Statuscodes erst dann wirklich helfen, wenn die Regeln sauber definiert sind.
Server-Fehler (5xx): intern kaputt, extern ehrlich
5xx bedeutet: Der Client hat nichts „falsch“ gemacht. Der Server konnte trotzdem nicht liefern. Das ist wichtig für Monitoring und Alarmierung.
500, 502, 503: was Monitoring daraus lesen kann
- 500 Internal Server Error: Unbehandelter Fehler, Ausnahme, Bug. Oft zu generisch – aber besser als 200 mit „error: true“.
- 502 Bad Gateway: Ein Proxy/Gateway (z. B. Nginx) bekommt eine schlechte Antwort vom Upstream (z. B. Node/ PHP-FPM).
- 503 Service Unavailable: Service ist temporär nicht verfügbar (Deployment, Wartung, Überlast). Kann mit „Retry-After“ ergänzt werden.
Praxis-Tipp: 500er sollten im Response-Body keine internen Stacktraces enthalten. Lieber eine allgemeine Message plus eine interne Correlation-ID (z. B. Request-ID) für Logs.
Fehler robust finden: Logs, nicht Bauchgefühl
Statuscodes zeigen, dass etwas schiefgeht. Für das Warum braucht es Logs. Für Python-Projekte hilft eine saubere Log-Strategie wie in Python Logging verstehen. Für PHP kann ein strukturierter Debugging-Prozess wie in PHP Debugging in der Praxis die Zeit bis zur Ursache deutlich senken.
Eine praxistaugliche Entscheidungslogik für APIs
Viele Teams diskutieren Statuscodes endlos. Besser ist eine einfache, wiederholbare Logik. Die folgenden Schritte funktionieren für CRUD-APIs (Create/Read/Update/Delete) und typische Webapps.
Kurze Schrittfolge für die Auswahl
- Ist die Anfrage erfolgreich? Dann 200/201/204 passend zur Aktion wählen.
- Fehlt Authentifizierung? 401.
- Ist Auth ok, aber keine Berechtigung? 403.
- Existiert die Ressource nicht? 404.
- Sind Daten formal kaputt (Syntax, fehlender JSON-Body)? 400.
- Sind Daten formal ok, aber Validierung/Regeln schlagen fehl? 422 (oder 409 bei Konflikt).
- Ist ein interner Fehler passiert? 500 (oder 502/503 je nach Infrastruktur).
Entscheidungsbaum für typische Fehlerfälle
- Anfrage scheitert
- Client muss etwas ändern
- Token fehlt/ungültig → 401
- Keine Rechte trotz Login → 403
- Ressource nicht da → 404
- Request ist kaputt (z. B. ungültiges JSON) → 400
- Request ist ok, aber Regeln/Validierung scheitern → 422
- Zustand kollidiert (z. B. Duplikat, Versionskonflikt) → 409
- Server ist schuld
- Bug/Unhandled Exception → 500
- Upstream/Proxy-Problem → 502
- Temporär nicht verfügbar/überlastet → 503
- Client muss etwas ändern
Fehlerantworten, die Frontends wirklich helfen
Ein guter Statuscode ist nur der Anfang. Frontends brauchen konsistente Antwortformen, um Fehler sauber anzuzeigen. Eine einfache Konvention kann so aussehen:
- Fehlerobjekt mit „message“ (kurz, nutzerfreundlich) und optional „details“ (technischer, für Formfelder)
- Ein stabiler „code“ (String), z. B. „EMAIL_TAKEN“, damit Frontends nicht auf Text parsen müssen
- Optional eine Request-ID, um Logs zu finden
Beispiel (gedanklich, ohne festes Format): Bei 422 kommen Feldfehler pro Eingabefeld, bei 401 ein Hinweis auf Login, bei 409 eine klare Konfliktursache. Wichtig ist, dass die API das konsistent durchzieht.
Warum „200 mit error=true“ langfristig schadet
Wenn Fehler als 200 zurückkommen, wirken Monitoring und Caching „gesund“, obwohl Nutzer:innen scheitern. Außerdem muss jede Client-Seite Sonderlogik bauen. Ein sauberer Statuscode plus klarer Body reduziert Komplexität auf allen Seiten.
Häufige Fragen aus der Praxis
Sollte eine API bei fehlenden Feldern 400 oder 422 senden?
Wenn der Request grundsätzlich nicht verarbeitet werden kann (z. B. JSON fehlt komplett oder ist nicht parsebar), passt 400. Wenn der Request parsebar ist, aber die Validierung scheitert (Pflichtfeld leer, Format falsch), ist 422 in der Praxis oft die klarere Wahl.
Ist 404 bei fehlender Berechtigung okay?
Manchmal ja: Wenn der Server absichtlich nicht verraten will, dass eine Ressource existiert (Sicherheits-/Privacy-Gründe). Dann wird 404 als „verstecktes 403“ genutzt. Wichtig ist, das bewusst zu entscheiden und konsistent umzusetzen.
Welche Statuscodes braucht ein kleines Projekt wirklich?
Für den Start reichen oft: 200, 201, 204, 400, 401, 403, 404, 409/422, 500. Mehr lohnt sich, wenn spezielle Anforderungen (Caching, Gateways, Wartungsfenster) dazukommen.

