Eine Liste von Statuscodes auswendig zu lernen ist leicht; den richtigen auszuwählen ist der schwierige Teil. Der Unterschied zwischen „diesen Datensatz habe ich nicht gefunden“ und „du darfst diesen Datensatz nicht sehen“ in einer API, ob aus einem POST bei einer Weiterleitung ein GET wird, ob Google eine Adresse wegen einer Fehlerseite aus dem Index nimmt – alles hängt an der Wahl der richtigen dreistelligen Zahl.
Dieser Beitrag hat zwei Teile: zuerst eine vollständige Liste (zum Nachschlagen), dann die Codes, die in der Praxis am häufigsten falsch gewählt werden, und wie sie in Next.js in Erscheinung treten.
Fünf Klassen
| Klasse | Bedeutung | Kurz gesagt |
|---|---|---|
| 1xx | Informational | Anfrage empfangen, Verarbeitung läuft weiter |
| 2xx | Successful | Anfrage erfolgreich verarbeitet |
| 3xx | Redirection | Weitere Schritte nötig, um abzuschließen |
| 4xx | Client Error | Der Fehler liegt beim Client |
| 5xx | Server Error | Der Fehler liegt beim Server |
Die Unterscheidung wirkt einfach, hat aber Grenzfälle: Der Client hat eine gültige Anfrage geschickt, der Server arbeitet korrekt, aber eine Geschäftsregel verbietet es – ist das 4xx oder 5xx? (Antwort: 4xx. Details weiter unten.)
1xx — Informational
| Code | Name | Bedeutung |
|---|---|---|
| 100 | Continue | Der Client kann den Request-Body weiter senden |
| 101 | Switching Protocols | Der Server wechselt auf das Protokoll aus dem Upgrade-Header (WebSocket-Handshake) |
| 102 | Processing | Anfrage empfangen, noch kein Ergebnis (WebDAV) |
| 103 | Early Hints | Hinweis zum Vorladen von Ressourcen per Link-Header, bevor die endgültige Antwort fertig ist |
In der Praxis ist 103 Early Hints der einzige moderne 1xx-Code, der wirklich nützlich ist: Während der Server die Hauptantwort vorbereitet, kann er dem Browser sagen: „Fang schon mal an, dieses CSS und diese Schrift zu laden.“
2xx — Successful
| Code | Name | Bedeutung |
|---|---|---|
| 200 | OK | Anfrage erfolgreich; die Bedeutung hängt von der HTTP-Methode ab |
| 201 | Created | Neue Ressource erstellt (meist POST/PUT) |
| 202 | Accepted | Empfangen, aber noch nicht verarbeitet – für asynchrone Jobs |
| 203 | Non-Authoritative Information | Metadaten stammen nicht vom Ursprungsserver (selten; besser 200) |
| 204 | No Content | Erfolgreich, kein Body – Header können trotzdem relevant sein |
| 205 | Reset Content | Der Client soll die Dokumentansicht zurücksetzen |
| 206 | Partial Content | Teilantwort auf eine Range-Anfrage (Video-Streaming, fortgesetzte Downloads) |
| 207 | Multi-Status | Separater Status für mehrere Ressourcen (WebDAV) |
| 208 | Already Reported | Vermeidet erneutes Auflisten von Mitgliedern (WebDAV) |
| 226 | IM Used | Antwort per Delta-Encoding geliefert |
Tipp: Nutze 201 und 204
Die meisten APIs geben für alles 200 zurück. Wenn aber ein Endpoint zum Erstellen 201 Created + einen Location-Header zurückgibt und ein Endpoint zum Löschen 204 No Content, weiß der Client sofort, was passiert ist, ohne einen Body parsen zu müssen.
3xx — Redirection
| Code | Name | Methode bleibt erhalten? | Dauerhaft? |
|---|---|---|---|
| 300 | Multiple Choices | — | — |
| 301 | Moved Permanently | Nein (Browser machen aus POST ein GET) | Dauerhaft |
| 302 | Found | Nein (POST → GET) | Temporär |
| 303 | See Other | Nein – wird immer zu GET | Temporär |
| 304 | Not Modified | — (Antwort aus dem Cache) | — |
| 305 | Use Proxy | ⚠️ Veraltet | — |
| 306 | (unused) | ⚠️ Reserviert | — |
| 307 | Temporary Redirect | Ja | Temporär |
| 308 | Permanent Redirect | Ja | Dauerhaft |
Diese ganze Tabelle läuft auf eine einzige Unterscheidung hinaus: Bleibt die HTTP-Methode nach der Weiterleitung erhalten?
- 301 / 302 sind Legacy-Codes. Browser wandeln dabei POST-Anfragen in GET um – auch wenn die Spezifikation das nicht ausdrücklich vorsah, ist das der De-facto-Standard.
- 307 / 308 wurden eingeführt, um diese Mehrdeutigkeit zu beseitigen: Die verwendete Methode bleibt unverändert. Wenn du einen POST weiterleitest, geht er als POST weiter.
- 303 macht genau das Gegenteil mit Absicht: Es erzwingt die Methode GET, egal was hereinkam.
Erklärung: Wofür ist 303 da?
Wenn ein Nutzer ein Formular abschickt, willst du ihn auf eine Ergebnisseite weiterleiten. Mit 307 landet er auch dort mit einer POST-Anfrage; lädt er die Seite neu, fragt der Browser „Möchtest du das Formular erneut senden?“, und du bekommst womöglich doppelte Datensätze. 303 verhindert diese Falle, indem es die Anfrage auf GET zwingt. Dieses Muster heißt POST/Redirect/GET und ist in Abläufen wie Payment-Callbacks entscheidend.
Warnung: Auswirkung auf SEO
Verwende 301/308 für dauerhafte Umzüge; Suchmaschinen nehmen die alte URL aus ihrem Index und übertragen die Link-Power auf die neue. Bei 302/307 bleibt die alte URL im Index. Die falsche Wahl bei Website-Migrationen ist eine der häufigsten Ursachen für Traffic-Verluste.
4xx — Client Error
| Code | Name | Bedeutung |
|---|---|---|
| 400 | Bad Request | Anfrage ist fehlerhaft: ungültige Syntax, Body nicht parsbar |
| 401 | Unauthorized | Bedeutet eigentlich „nicht authentifiziert“ – Login erforderlich |
| 402 | Payment Required | Zahlung erforderlich; keine Standardverwendung |
| 403 | Forbidden | Der Server weiß, wer du bist, aber du hast keine Berechtigung |
| 404 | Not Found | Ressource fehlt – oder ihre Existenz soll verborgen bleiben |
| 405 | Method Not Allowed | Methode wird erkannt, aber für diese Ressource nicht unterstützt |
| 406 | Not Acceptable | Die Content Negotiation ergab kein akzeptables Format |
| 407 | Proxy Authentication Required | Wie 401, aber für einen Proxy-Server |
| 408 | Request Timeout | Inaktive Verbindung vom Server geschlossen |
| 409 | Conflict | Anfrage steht im Konflikt mit dem aktuellen Zustand der Ressource |
| 410 | Gone | Dauerhaft gelöscht, die Adresse existiert nicht mehr |
| 411 | Length Required | Content-Length-Header erforderlich |
| 412 | Precondition Failed | Vorbedingung einer bedingten Anfrage nicht erfüllt |
| 413 | Content Too Large | Request-Body überschreitet die Server-Limits |
| 414 | URI Too Long | Ziel-URL ist zu lang |
| 415 | Unsupported Media Type | Format des Request-Payloads wird nicht unterstützt |
| 416 | Range Not Satisfiable | Angeforderter Bereich kann nicht geliefert werden |
| 417 | Expectation Failed | Erwartung aus dem Expect-Header konnte nicht erfüllt werden |
| 418 | I'm a teapot | Scherz-Code (RFC 2324) – Teekannen können keinen Kaffee kochen |
| 421 | Misdirected Request | Anfrage an den falschen Server geschickt |
| 422 | Unprocessable Content | Syntax ist korrekt, aber der semantische Inhalt ist ungültig |
| 423 | Locked | Ressource ist gesperrt (WebDAV) |
| 424 | Failed Dependency | Vorherige Anfrage ist fehlgeschlagen (WebDAV) |
| 425 | Too Early | Verweigert die Verarbeitung einer Anfrage, die wiederholt werden könnte (TLS-1.3-Early-Data) |
| 426 | Upgrade Required | Der Client muss das Protokoll wechseln |
| 428 | Precondition Required | Bedingte Anfrage erforderlich – verhindert das „Lost Update“-Problem |
| 429 | Too Many Requests | Rate Limit überschritten |
| 431 | Request Header Fields Too Large | Header sind zu groß |
| 451 | Unavailable For Legal Reasons | Zugriff aus rechtlichen Gründen gesperrt |
401 oder 403?
Das am häufigsten verwechselte Paar. Die Namen führen in die Irre, denn 401 bedeutet eigentlich „nicht authentifiziert“:
- 401 – Ich weiß nicht, wer du bist. Melde dich an. (Keine Session oder ungültiges Token.)
- 403 – Ich weiß, wer du bist, aber auf diese Ressource darfst du nicht zugreifen. (Ein Nutzer mit der Rolle
user, der/adminaufrufen will.)
Tipp: Eine dritte Option: 404
Manchmal verrät schon 403 zu viel. „Diese Ressource existiert, aber du darfst sie nicht sehen“ gibt Informationen preis. Mit 404 die Existenz einer Ressource komplett zu verbergen – wie GitHub es bei privaten Repositories macht – ist ein legitimer Ansatz.
400 oder 422?
- 400 – Ich konnte die Anfrage nicht parsen. Kaputtes JSON, fehlendes Pflichtfeld, falscher Datentyp.
- 422 – Ich habe sie geparst und das Format ist gültig, aber die Bedeutung ist ungültig. „Das Enddatum darf nicht vor dem Startdatum liegen“, „diese E-Mail-Adresse ist bereits registriert“.
Anders gesagt: Syntaxfehler sind 400, Verstöße gegen Geschäftsregeln sind 422. In der Praxis geben viele APIs für beides 400 zurück, das ist in Ordnung – aber wenn du sie trennst, können Client-Anwendungen „Formular korrigieren“ und „Anfrageformat korrigieren“ ohne zusätzlichen Code unterscheiden.
409 und 410
- 409 Conflict – Die Anfrage steht im Konflikt mit dem aktuellen Zustand der Ressource. Versionskonflikt bei gleichzeitiger Bearbeitung oder der Versuch, eine Ressource mit einem bereits vorhandenen Slug anzulegen.
- 410 Gone – Die Ressource existierte, wurde dauerhaft gelöscht und kommt nicht wieder. Der Unterschied zu
404ist die Gewissheit: Suchmaschinen entfernen eine410deutlich schneller aus dem Index. Wenn du dir nicht sicher bist, bleib bei404.
429 und Retry-After
Wenn du Rate Limiting implementierst, ist allein 429 zurückzugeben nur die halbe Arbeit. Sende auch einen Retry-After-Header – damit der Client weiß, wie lange er warten muss, statt blind erneut zu versuchen.
Beispiel: Rate Limiting in einem Next.js Route Handler
export async function POST(req: Request) {
const allowed = await rateLimit(req);
if (!allowed) {
return new Response(
JSON.stringify({ error: "Çok fazla istek gönderdiniz." }),
{
status: 429,
headers: {
"Content-Type": "application/json",
"Retry-After": "60", // seconds
},
}
);
}
// ...
}451
Wird verwendet, wenn Inhalte aus rechtlichen Gründen gesperrt sind. Benannt nach Ray Bradburys Roman Fahrenheit 451 – der Temperatur, bei der Papier brennt.
5xx — Server Error
| Code | Name | Bedeutung |
|---|---|---|
| 500 | Internal Server Error | Allgemeiner Fehler; der Server ist auf einen unerwarteten Zustand gestoßen |
| 501 | Not Implemented | Der Server unterstützt die Anfragemethode nicht |
| 502 | Bad Gateway | Der Proxy hat vom Upstream-Server eine ungültige Antwort erhalten |
| 503 | Service Unavailable | Der Server kann die Anfrage vorübergehend nicht bearbeiten (Wartung, Überlast) |
| 504 | Gateway Timeout | Der Upstream-Server hat nicht rechtzeitig geantwortet |
| 505 | HTTP Version Not Supported | HTTP-Version wird nicht unterstützt |
| 506 | Variant Also Negotiates | Fehler in der Serverkonfiguration (zirkuläre Negotiation) |
| 507 | Insufficient Storage | Speicherplatz erschöpft (WebDAV) |
| 508 | Loop Detected | Endlosschleife erkannt (WebDAV) |
| 510 | Not Extended | Erforderliche HTTP-Erweiterung wird nicht unterstützt |
| 511 | Network Authentication Required | Der Client muss sich authentifizieren, um Netzwerkzugang zu erhalten (WLAN-Portal) |
502, 503, 504 – welcher Fehler ist welcher?
Diese drei sind der schnellste Weg, Probleme bei Server-Deployments zu diagnostizieren:
- 502 Bad Gateway – Nginx läuft, aber die App dahinter ist abgestürzt oder antwortet auf diesem Port nicht. Schau in die Logs deiner App.
- 503 Service Unavailable – Der Server läuft, verweigert aber gerade den Traffic: Wartungsmodus, Systemüberlastung, keine Instanz im Pool verfügbar. Sollte mit
Retry-Aftergesendet und darf nicht gecacht werden. - 504 Gateway Timeout – Die Upstream-App existiert, ist aber zu langsam; der Proxy hat das Warten aufgegeben. Such nach langsamen Queries oder langsamen Aufrufen externer APIs.
Achtung: Gib im Wartungsmodus nicht 200 zurück
Wenn du eine „Wir führen gerade Wartungsarbeiten durch“-Seite mit Status 200 auslieferst, glauben Suchmaschinen, das sei dein eigentlicher Inhalt. Wartungsseiten sollten 503 zurückgeben – Suchmaschinen strafen dein Ranking bei kurzen Ausfällen nicht ab.
Statuscodes in Next.js
Das Framework wählt einige Statuscodes für dich aus, und es hilft zu wissen, was es im Hintergrund nimmt.
Wichtig: Redirect-Funktionen
redirect()→ 307 (temporär, Methode bleibt erhalten)permanentRedirect()→ 308 (dauerhaft, Methode bleibt erhalten)redirect()innerhalb eines Server-Action-Formular-Submits → 303 (damit der Browser mit GET nachfragt; ist JS aktiv, übernimmt ohnehin die clientseitige Navigation)NextResponse.redirect()→ standardmäßig 307
Next.js nimmt 307/308 statt 302/301 wegen des oben erwähnten Problems mit der Methode: Ein Browser, der 302 erhält, wandelt POST in GET um, und aus einem POST an /users wird ein GET an /people.
Wenn du eine Adresse dauerhaft änderst, nimm permanentRedirect() statt redirect() – oder setze permanent: true in der redirects()-Konfiguration deiner next.config.ts. Sonst nehmen Suchmaschinen die alte Adresse nicht aus dem Index.
notFound() gibt 404 zurück und rendert deine Datei not-found.tsx.
Beispiel: Korrekte Statuscodes in einem Route Handler
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const body = await req.json().catch(() => null);
if (!body) {
return NextResponse.json({ error: "Geçersiz JSON" }, { status: 400 });
}
const parsed = schema.safeParse(body);
if (!parsed.success) {
// Valid format, invalid meaning
return NextResponse.json(
{ error: "Doğrulama hatası", issues: parsed.error.issues },
{ status: 422 }
);
}
const session = await auth();
if (!session) {
return NextResponse.json({ error: "Giriş gerekli" }, { status: 401 });
}
if (session.user.role !== "admin") {
return NextResponse.json({ error: "Yetkiniz yok" }, { status: 403 });
}
const created = await db.post.create({ data: parsed.data });
return NextResponse.json(created, {
status: 201,
headers: { Location: `/api/posts/${created.id}` },
});
}Schnelle Entscheidungshilfe
Zusammenfassung: Welchen Code soll ich zurückgeben?
- Datensatz erstellt → 201 +
Location - Gelöscht, nichts zurückzugeben → 204
- URL dauerhaft geändert → 308 (
301ist für SEO ebenfalls in Ordnung) - Weiterleitung auf die Ergebnisseite nach Formular-Submit → 303
- Nicht authentifiziert → 401
- Authentifiziert, aber nicht berechtigt → 403
- Existenz des Datensatzes verbergen → 404
- Kaputtes JSON → 400
- Gültiges JSON, Verstoß gegen Geschäftsregel → 422
- Konflikt bei gleichzeitiger Bearbeitung → 409
- Rate Limit erreicht → 429 +
Retry-After - Wartungsarbeiten → 503 +
Retry-After - Unerwarteter Fehler → 500 (den tatsächlichen Grund ins Log schreiben, nicht an den Nutzer)
Eine letzte Anmerkung: Gib in Fehlerantworten niemals Stacktraces an Nutzer heraus. Statuscodes sagen dem Client, was er tun soll; detaillierte Informationen gehören in die Server-Logs.
Hinweis: Quellen
Die Liste der Statuscodes basiert auf der Referenz MDN HTTP response status codes, das Verhalten von Next.js folgt der redirect-Dokumentation.
Interaktive Roadmap & Tool
Junior Frontend Developer 2026
Was du wirklich wissen musst, um 2026 einen Junior-Frontend-Job zu bekommen, und was warten kann – abgeleitet aus echten Stellenanzeigen.
SQL oder NoSQL?
Beantworte sechs Fragen, und ich sage dir, welche Art von Datenbank zu deinem Projekt passt und warum.