Jede HTTP-Antwort beginnt mit einer dreistelligen Zahl, und diese Zahl ist die wichtigste Information für jeden Client. Sie entscheidet, ob ein Browser etwas anzeigt, ob ein Skript einen Fehler meldet, ob ein Client eine Anfrage wiederholt oder aufgibt. Trotzdem werden HTTP-Statuscodes in vielen APIs nachlässig oder schlicht falsch gesetzt. Dieser Artikel räumt damit auf: Du lernst die Logik hinter den Codes, die wichtigsten Vertreter und wie du daraus eine saubere Fehlerbehandlung baust.
Die fünf Klassen verstehen
Die erste Ziffer eines Statuscodes verrät dir bereits die grobe Bedeutung. Wer diese fünf Klassen kennt, versteht jeden Code, auch unbekannte:
- 1xx – Informational: Die Anfrage läuft, eine vorläufige Antwort. Selten direkt sichtbar.
- 2xx – Success: Alles hat geklappt.
- 3xx – Redirection: Weitere Schritte nötig, meist eine Weiterleitung.
- 4xx – Client Error: Der Fehler liegt beim Aufrufer – falsche Eingabe, fehlende Berechtigung, falsche URL.
- 5xx – Server Error: Der Fehler liegt beim Server. Die Anfrage war in Ordnung, aber der Server konnte sie nicht verarbeiten.
Die Trennung zwischen 4xx und 5xx ist entscheidend: Sie sagt dem Client, wer das Problem hat – und damit, ob ein erneuter Versuch überhaupt Sinn ergibt.
Die 2xx-Erfolge im Detail
- 200 OK – der Allrounder. Anfrage erfolgreich, Antwort im Body.
- 201 Created – eine neue Ressource wurde angelegt. Setze idealerweise einen
Location-Header auf die URL der neuen Ressource. - 202 Accepted – die Anfrage wurde angenommen, aber noch nicht abgeschlossen. Ideal für asynchrone Verarbeitung, etwa wenn ein langlaufender Job angestoßen wird.
- 204 No Content – Erfolg, aber kein Antwortkörper. Typisch nach einem DELETE oder einem Update ohne Rückgabewert.
Den Unterschied zwischen 200 und 201 wirklich zu nutzen, signalisiert dem Client klar, dass etwas Neues entstanden ist – ein kleines Detail, das deine API professionell wirken lässt.
Die 3xx-Weiterleitungen
Bei Weiterleitungen kommt es auf eine feine Unterscheidung an. 301 Moved Permanently signalisiert eine dauerhafte Verschiebung – Suchmaschinen und Clients merken sich die neue Adresse. 302 Found und 307 Temporary Redirect sind nur vorübergehend. 304 Not Modified ist im API-Kontext besonders wertvoll: In Kombination mit Caching-Headern wie ETag erlaubt es dem Client, eine Ressource nur dann erneut zu laden, wenn sie sich geändert hat – das spart Bandbreite.
Die 4xx-Clientfehler – hier passieren die meisten Fehler
Diese Klasse wird am häufigsten falsch verwendet. Wähle den Code, der die Ursache am genauesten beschreibt:
- 400 Bad Request – die Anfrage ist syntaktisch fehlerhaft oder unverständlich.
- 401 Unauthorized – Authentifizierung fehlt oder ist ungültig. Der Name ist irreführend: Es geht um fehlende Anmeldung, nicht um fehlende Rechte.
- 403 Forbidden – du bist angemeldet, darfst aber auf diese Ressource nicht zugreifen.
- 404 Not Found – die Ressource existiert nicht (oder soll dem Aufrufer als nicht existent erscheinen).
- 405 Method Not Allowed – die HTTP-Methode passt nicht zur Ressource, etwa ein DELETE auf einen nur lesbaren Endpunkt.
- 409 Conflict – ein Konflikt mit dem aktuellen Zustand, etwa eine doppelte E-Mail-Adresse.
- 422 Unprocessable Entity – die Syntax stimmt, aber die Daten sind inhaltlich ungültig. Sehr beliebt für Validierungsfehler.
- 429 Too Many Requests – der Client hat das Rate-Limit überschritten. Gib einen
Retry-After-Header mit.
Der Unterschied zwischen 401 und 403 ist ein Klassiker im Vorstellungsgespräch: 401 heißt „Ich weiß nicht, wer du bist", 403 heißt „Ich weiß, wer du bist, aber du darfst das nicht". Für die feine Trennung zwischen 400 und 422 bei Validierungsfehlern lohnt zudem ein Blick auf unsere Empfehlungen zur API-Authentifizierung, wenn es um 401 und 403 geht.
Die 5xx-Serverfehler
- 500 Internal Server Error – der Sammelcode für unerwartete Fehler. Wenn du 500 zurückgibst, ist meist ein Bug oder eine unbehandelte Exception schuld.
- 502 Bad Gateway – ein vorgeschalteter Proxy oder Gateway hat eine ungültige Antwort vom eigentlichen Server bekommen.
- 503 Service Unavailable – der Server ist vorübergehend überlastet oder in Wartung. Hier passt ein
Retry-After-Header. - 504 Gateway Timeout – ein Upstream-Server hat nicht rechtzeitig geantwortet.
Wichtig: Ein 500er sollte nie ein erwarteter Fehler sein. Validierungsprobleme, fehlende Berechtigungen oder nicht gefundene Ressourcen gehören in die 4xx-Klasse. Landet ein vorhersehbarer Fall als 500 beim Client, deutet das auf einen Bug in deiner Fehlerbehandlung hin.
Statuscode und Fehlerbody gehören zusammen
Ein Statuscode allein reicht nicht. Ein 422 sagt „Validierung fehlgeschlagen", aber nicht welches Feld. Liefere deshalb zusätzlich einen strukturierten Fehlerkörper in JSON. Bewährt hat sich der Standard RFC 9457 (Problem Details), der ein einheitliches Schema vorgibt. Ein guter Fehlerkörper enthält:
- einen maschinenlesbaren Code, auf den der Client verlässlich reagieren kann (z. B.
email_already_exists), - eine menschenlesbare Nachricht für Entwickler,
- bei Validierungsfehlern eine Liste der betroffenen Felder mit konkreten Hinweisen,
- eine Request-ID, um den Fall im Log wiederzufinden.
Die wichtigste Sicherheitsregel: Niemals interne Details preisgeben. Stacktraces, Datenbankfehler, Dateipfade oder Framework-Versionen verraten Angreifern wertvolle Informationen. Logge diese Details serverseitig und gib dem Client nur eine generische Meldung samt Request-ID, mit der dein Support den Fall nachvollziehen kann.
Retries: Wann darf wiederholt werden?
Die Statuscode-Klasse steuert das Wiederholungsverhalten von Clients. Ein 5xx-Fehler oder ein 429 ist oft vorübergehend – hier ist ein Retry sinnvoll, am besten mit exponential backoff (wachsende Wartezeit zwischen den Versuchen) und etwas Zufall (Jitter), damit nicht alle Clients gleichzeitig erneut anfragen. Ein 4xx-Fehler wie 400 oder 422 hingegen wird sich beim einfachen Wiederholen nie ändern – hier muss erst die Anfrage korrigiert werden.
Eng damit verbunden ist die Idempotenz: Wiederholt ein Client einen Schreibvorgang, darf er nicht zweimal ausgeführt werden. GET, PUT und DELETE sind von Natur aus idempotent; für POST schützt ein Idempotency-Key, den der Client mitschickt und den der Server zur Erkennung von Wiederholungen nutzt. Dasselbe Prinzip ist zentral bei Webhooks, die ebenfalls mehrfach zugestellt werden können.
Praktische Empfehlungen
- Wähle immer den spezifischsten passenden Code, nicht pauschal 200 oder 500.
- Halte den Statuscode und den Fehlerkörper konsistent über die ganze API hinweg.
- Setze bei 429 und 503 einen
Retry-After-Header. - Verrate in Fehlermeldungen keine internen Details.
- Dokumentiere zu jedem Endpunkt, welche Codes er zurückgeben kann.
Wie diese Codes in das große Ganze einer durchdachten Schnittstelle passen, zeigt unser Leitfaden zu REST-API-Design. Weitere Helfer für Entwickler findest du in unseren Webtools.
Häufige Fragen
Was ist der Unterschied zwischen 401 und 403?
401 Unauthorized bedeutet, dass keine oder eine ungültige Authentifizierung vorliegt – der Server weiß nicht, wer du bist. 403 Forbidden bedeutet, dass du zwar authentifiziert bist, aber nicht die nötigen Rechte für diese Ressource hast.
Soll ich 400 oder 422 für Validierungsfehler nehmen?
Beides ist verbreitet. 400 nutzt man eher, wenn die Anfrage syntaktisch fehlerhaft ist, 422, wenn die Syntax stimmt, aber die Werte inhaltlich ungültig sind. Wichtig ist vor allem, dass du dich für eine Variante entscheidest und sie konsistent verwendest.
Darf ich einen Fehler mit Status 200 zurückgeben?
Technisch ja, aber du solltest es nicht tun. Wenn du Erfolg meldest und den Fehler in den Body packst, zwingst du jeden Client, den Body zu parsen, statt einfach den Statuscode zu prüfen. Das bricht mit den Erwartungen aller HTTP-Werkzeuge und macht deine API schwerer nutzbar.
Wann sollte ein Client eine Anfrage wiederholen?
Bei 5xx-Fehlern und 429 ist ein Retry mit exponentiell wachsender Wartezeit sinnvoll, weil das Problem oft vorübergehend ist. Bei 4xx-Fehlern wie 400 oder 404 bringt ein Wiederholen nichts – hier muss erst die Anfrage selbst korrigiert werden.