← Alle Artikel
Zuletzt aktualisiert: 2026-03-30

API gibt 500-Fehler zurück? REST-API-Probleme systematisch debuggen

Systematische REST-API-Debugging-Anleitung. CORS-Fehler, 500/502/503-Fehler, Timeouts, Authentifizierungsprobleme.

Kurzfassung

Wenn Ihre REST-API 500-Fehler liefert, gehen Sie in dieser Reihenfolge vor: Fehler reproduzieren, die fehlerhafte Komponente isolieren und den Request mithilfe von Logs und curl durch den gesamten Stack nachverfolgen. Die meisten 500-Fehler entstehen durch nicht abgefangene Exceptions, fehlgeschlagene Datenbankverbindungen oder falsch konfigurierte Umgebungsvariablen. Schauen Sie zuerst in die Server-Logs — dort steht fast immer die Antwort.

Voraussetzungen

Schritt 1: Systematisches Vorgehen — Reproduzieren, Isolieren, Nachverfolgen

Reproduzieren

Bevor Sie irgendetwas debuggen, brauchen Sie einen zuverlaessigen Weg, den Fehler auszuloesen. Dokumentieren Sie den exakten Request, der fehlschlaegt:

# Den fehlerhaften Request speichern, um ihn wiederholen zu koennen
curl -v -X POST https://api.example.com/v1/users \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer IHR_TOKEN" \
  -d '{"name": "Test", "email": "test@example.com"}' \
  2>&1 | tee /tmp/api-debug.log

Stellen Sie sich folgende Fragen: Tritt der Fehler jedes Mal auf? Nur bei bestimmten Daten? Nur zu bestimmten Uhrzeiten? Sporadische Fehler deuten haeufig auf Ressourcenknappheit oder Race Conditions hin.

Isolieren

Grenzen Sie ein, welche Komponente den Fehler verursacht. Ein typischer REST-API-Stack hat mehrere Schichten:

Client → DNS → Load Balancer → Reverse Proxy (Nginx) → App-Server → Datenbank

Testen Sie jede Schicht einzeln. Antwortet Nginx? Kann der App-Server die Datenbank erreichen?

# Pruefen, ob Nginx ueberhaupt antwortet
curl -I https://api.example.com/health

# App-Server direkt testen (Reverse Proxy umgehen)
curl -I http://localhost:3000/health

# Datenbankverbindung vom App-Server aus pruefen
mysql -u appuser -p -h db-host -e "SELECT 1;"
# oder fuer PostgreSQL
psql -U appuser -h db-host -c "SELECT 1;"

Nachverfolgen

Verfolgen Sie den Request durch jede Schicht. Aktivieren Sie voruebergehend ausfuehrliches Logging und nutzen Sie Request-IDs, falls Ihre Anwendung diese unterstuetzt:

# Eigene Request-ID mitschicken, um den Request in den Logs zu finden
curl -v -X GET https://api.example.com/v1/orders \
  -H "X-Request-ID: debug-12345" \
  -H "Authorization: Bearer IHR_TOKEN"

Durchsuchen Sie anschliessend die Logs aller Dienste nach dieser ID.

Schritt 2: Server-Logs lesen

Logs sind Ihr wichtigstes Debugging-Werkzeug. Wo sie liegen, haengt von Ihrem Setup ab:

systemd-Dienste (journalctl)

# Logs eines bestimmten Dienstes anzeigen, neueste zuerst
journalctl -u my-api-service -n 100 --no-pager

# Logs in Echtzeit verfolgen (wie tail -f)
journalctl -u my-api-service -f

# Nach Zeitraum filtern
journalctl -u my-api-service --since "2024-01-15 14:00" --until "2024-01-15 15:00"

# Nur Fehlermeldungen anzeigen
journalctl -u my-api-service -p err -n 50

Docker-Container

# Die letzten 200 Zeilen der Container-Logs anzeigen
docker logs --tail 200 my-api-container

# Logs in Echtzeit mit Zeitstempeln verfolgen
docker logs -f --timestamps my-api-container

# Bei Docker-Compose-Setups
docker-compose logs -f --tail=100 api

PM2 (Node.js)

# Logs einer bestimmten App anzeigen
pm2 logs my-api --lines 100

# Nur Fehler-Logs anzeigen
pm2 logs my-api --err --lines 50

# Logs leeren und neu starten
pm2 flush my-api

Klassische Log-Dateien

# Nginx-Fehlerlog
tail -f /var/log/nginx/error.log

# Nginx-Zugriffslog — nach 500-Fehlern filtern
grep ' 500 ' /var/log/nginx/access.log | tail -20

# Anwendungslogs (uebliche Speicherorte)
tail -f /var/log/myapp/error.log
tail -f /var/log/syslog | grep myapp

Schritt 3: Testen mit curl

curl ist das vielseitigste Werkzeug zum API-Debugging. Verinnerlichen Sie diese Muster:

Grundlegende Requests mit ausfuehrlicher Ausgabe

# GET-Request mit allen Headers (-v fuer verbose)
curl -v https://api.example.com/v1/users

# Nur Response-Headers anzeigen
curl -I https://api.example.com/v1/users

# Response-Headers UND Body anzeigen
curl -i https://api.example.com/v1/users

POST-Requests mit JSON-Daten

# POST mit JSON-Body
curl -X POST https://api.example.com/v1/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Maria Mueller", "email": "maria@example.com", "role": "admin"}'

# POST mit Daten aus einer Datei
curl -X POST https://api.example.com/v1/import \
  -H "Content-Type: application/json" \
  -d @payload.json

# PUT-Request zum Aktualisieren einer Ressource
curl -X PUT https://api.example.com/v1/users/42 \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer eyJhbGciOi..." \
  -d '{"name": "Maria Schmidt"}'

Verbindungsprobleme analysieren

# Timing-Informationen anzeigen
curl -o /dev/null -s -w "DNS: %{time_namelookup}s\nVerbindung: %{time_connect}s\nTLS: %{time_appconnect}s\nErstes Byte: %{time_starttransfer}s\nGesamt: %{time_total}s\nHTTP-Code: %{http_code}\n" https://api.example.com/v1/health

# Zu einer bestimmten IP aufloesen (DNS umgehen)
curl --resolve api.example.com:443:10.0.0.5 https://api.example.com/v1/health

# Eigenes Timeout setzen (5 Sekunden)
curl --max-time 5 --connect-timeout 3 https://api.example.com/v1/slow-endpoint

Schritt 4: HTTP-Statuscodes verstehen

Jeder Statuscode erzaehlt eine bestimmte Geschichte. Hier ist, was sie in der Praxis bedeuten:

400 Bad Request

Bedeutung: Der Server kann den Request nicht verarbeiten, weil die Syntax fehlerhaft oder die Daten ungueltig sind.

Haeufige Ursachen: Fehlende Pflichtfelder, falsche Datentypen, ungueltige JSON-Syntax, Feldlaengen-Limits ueberschritten.

# Wird wahrscheinlich einen 400-Fehler zurueckgeben — ungueltiges JSON
curl -X POST https://api.example.com/v1/users \
  -H "Content-Type: application/json" \
  -d '{name: "Anfuehrungszeichen am Key fehlen"}'

401 Unauthorized

Bedeutung: Die Authentifizierung fehlt oder ist ungueltig. Der Server weiss nicht, wer Sie sind.

Haeufige Ursachen: Fehlender Authorization-Header, abgelaufenes Token, falscher API-Key.

403 Forbidden

Bedeutung: Die Authentifizierung war erfolgreich, aber Sie haben keine Berechtigung fuer diese Aktion. Der Server weiss, wer Sie sind — aber Sie duerfen das nicht.

Haeufige Ursachen: Unzureichende Rolle oder Berechtigung, IP-Allowlist-Beschraenkung, Ressource gehoert einem anderen Benutzer.

404 Not Found

Bedeutung: Die angeforderte Ressource existiert unter dieser URL nicht.

Haeufige Ursachen: Tippfehler in der URL, Ressource wurde geloescht, falsches API-Versions-Praefix, fehlender Trailing Slash.

500 Internal Server Error

Bedeutung: Der Server ist auf einen unerwarteten Zustand gestossen. Dies ist immer ein serverseitiger Fehler.

Haeufige Ursachen: Nicht abgefangene Exceptions, Null-Pointer-Fehler, fehlende Umgebungsvariablen, Datenbankverbindungsfehler, Speichermangel.

502 Bad Gateway

Bedeutung: Der Reverse Proxy (Nginx, Apache) hat eine ungueltige Antwort vom vorgelagerten App-Server erhalten.

Haeufige Ursachen: App-Server abgestuerzt, App-Server laeuft nicht, falscher Upstream-Port in der Proxy-Konfiguration.

503 Service Unavailable

Bedeutung: Der Server kann voruebergehend keine Anfragen verarbeiten.

Haeufige Ursachen: Server startet gerade, Wartungsmodus, Ueberlastung, Abhaengigkeit (Datenbank) ist nicht erreichbar.

504 Gateway Timeout

Bedeutung: Der Reverse Proxy hat zu lange auf eine Antwort vom Upstream-Server gewartet.

Haeufige Ursachen: Langsame Datenbankabfragen, haengende externe API-Aufrufe, zu niedrig konfigurierte Proxy-Timeouts.

Schritt 5: CORS-Fehler beheben

Cross-Origin Resource Sharing (CORS)-Fehler treten nur im Browser auf. Wenn Ihre API mit curl funktioniert, aber im Browser mit "CORS policy"-Fehlern scheitert, muss die Loesung serverseitig erfolgen.

CORS-Probleme erkennen

# Einen CORS-Preflight-Request simulieren
curl -v -X OPTIONS https://api.example.com/v1/users \
  -H "Origin: https://app.example.com" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: Content-Type, Authorization"

# Pruefen Sie die Antwort auf folgende Header:
# Access-Control-Allow-Origin: https://app.example.com
# Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
# Access-Control-Allow-Headers: Content-Type, Authorization

Nginx-CORS-Konfiguration

# /etc/nginx/conf.d/api.conf
server {
    listen 443 ssl;
    server_name api.example.com;

    location /v1/ {
        # CORS-Header
        add_header Access-Control-Allow-Origin "https://app.example.com" always;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
        add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-Request-ID" always;
        add_header Access-Control-Max-Age 86400 always;

        # Preflight-Requests behandeln
        if ($request_method = OPTIONS) {
            return 204;
        }

        proxy_pass http://localhost:3000;
    }
}

Express.js-CORS-Konfiguration

const cors = require('cors');

app.use(cors({
  origin: ['https://app.example.com', 'https://staging.example.com'],
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-Request-ID'],
  credentials: true,
  maxAge: 86400
}));

Wichtig: Verwenden Sie niemals Access-Control-Allow-Origin: * zusammen mit credentials: true. Browser lehnen diese Kombination ab. Geben Sie immer die exakte Origin an.

Schritt 6: Timeout-Probleme

Timeouts koennen auf jeder Schicht auftreten. Identifizieren Sie, wo das Timeout passiert:

# Antwortzeiten aufgeschluesselt messen
curl -w "\n---Zeitmessung---\nDNS:        %{time_namelookup}s\nVerbindung: %{time_connect}s\nTLS:        %{time_appconnect}s\nErstes Byte: %{time_starttransfer}s\nGesamt:     %{time_total}s\n" \
  -o /dev/null -s https://api.example.com/v1/reports/generate

Wenn time_starttransfer hoch, aber time_connect niedrig ist, braucht der Server lange fuer die Verarbeitung. Ist time_connect hoch, liegt ein Netzwerk- oder DNS-Problem vor.

Gaengige Timeout-Konfigurationen

# Nginx — Proxy-Timeout fuer langsame Endpunkte erhoehen
location /v1/reports/ {
    proxy_pass http://localhost:3000;
    proxy_read_timeout 120s;
    proxy_connect_timeout 10s;
    proxy_send_timeout 60s;
}

# Node.js — Server-Timeout erhoehen
const server = app.listen(3000);
server.setTimeout(120000); // 120 Sekunden

Schritt 7: JWT- und OAuth-Debugging

Authentifizierungsprobleme gehoeren zu den haeufigsten API-Fehlern. So untersuchen Sie Tokens:

JWT-Token inspizieren

Ein JWT besteht aus drei Teilen, getrennt durch Punkte: Header.Payload.Signatur. Die ersten beiden Teile lassen sich ohne Secret dekodieren:

# JWT-Payload im Terminal dekodieren (kein Secret noetig)
echo 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMiwiZXhwIjoxNTE2MjQyNjIyfQ.signature' \
  | cut -d'.' -f2 \
  | base64 -d 2>/dev/null | python3 -m json.tool

Pruefen Sie auf diese haeufigen Probleme:

Sie koennen Tokens auch auf jwt.io einfuegen, um sie visuell zu analysieren (fuegen Sie niemals Produktions-Tokens mit sensiblen Daten ein).

OAuth-Flows testen

# Neues Token mit Client-Credentials-Grant anfordern
curl -X POST https://auth.example.com/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=IHRE_CLIENT_ID" \
  -d "client_secret=IHR_CLIENT_SECRET" \
  -d "scope=read write"

# Das zurueckgegebene access_token verwenden
curl -H "Authorization: Bearer ACCESS_TOKEN_HIER" \
  https://api.example.com/v1/protected-resource

Schritt 8: Postman und HTTPie

HTTPie — Die benutzerfreundliche curl-Alternative

# Installation
brew install httpie    # macOS
apt install httpie     # Ubuntu/Debian

# GET-Request (formatiert JSON automatisch)
http GET https://api.example.com/v1/users Authorization:"Bearer TOKEN"

# POST mit JSON (Content-Type muss nicht angegeben werden)
http POST https://api.example.com/v1/users name="Maria" email="maria@example.com"

# Request- und Response-Headers anzeigen
http -v POST https://api.example.com/v1/users name="Maria"

# Antwort in Datei speichern
http --download https://api.example.com/v1/export

Postman-Tipps

Schnellreferenz zur Fehlerbehebung

SymptomWahrscheinliche UrsacheErster Schritt
500 auf allen EndpunktenApp-Absturz, fehlende Umgebungsvariable, DB nicht erreichbarAnwendungslogs pruefen
500 auf einem EndpunktNicht abgefangene Exception in dieser RouteLogs nach Stack-Trace durchsuchen
502 Bad GatewayApp-Server laeuft nichtsystemctl status myapp
504 Gateway TimeoutLangsame Abfrage oder externer Aufrufcurl-Timing und DB-Slow-Log pruefen
CORS-Fehler im BrowserFehlende Response-HeaderMit curl OPTIONS-Request testen
401 trotz gueltigem TokenToken abgelaufen oder falsches AudienceJWT dekodieren, exp-Claim pruefen
Funktioniert in Postman, scheitert im BrowserCORS- oder Cookie-ProblemPreflight-Antwort ueberpruefen
Sporadische 500-FehlerRessourcenknappheit, Race ConditionSpeicher/CPU ueberwachen, Connection Pool pruefen

Vorbeugung und Best Practices

Experten-Hilfe gebraucht?

Ursache nicht gefunden? Ich debugge live. €49.

Jetzt buchen — €49

100% Geld-zurück-Garantie

HR

Harald Roessler

Infrastructure Engineer mit 20+ Jahren Erfahrung. Gründer der DSNCON GmbH.