> Die vollständige Liste der Artikel steht in [llms.txt](https://docs.f3cloud.com/llms.txt). Jede Seite gibt es auch als Markdown, dazu einfach .md an die Adresse anhängen. Diese Seite als Markdown: [https://docs.f3cloud.com/de/web/site-errors-502-504-403-500.md](https://docs.f3cloud.com/de/web/site-errors-502-504-403-500.md).

# Nginx-Fehler 502, 504, 403 und 500 – was sie bedeuten und wie Sie sie beheben

Was die Fehler 502 Bad Gateway, 504 Gateway Time-out, 403 Forbidden und 500 Internal Server Error auf einem Server mit Nginx bedeuten und wie Sie sie beheben. Die Kette vom Browser bis zur Anwendung, Diagnose mit curl, das Protokoll error.log und systemctl, Analyse der häufigsten Ursachen anhand echter Zeilen aus dem Protokoll, Einstellung von Timeouts und Zugriffsrechten. Getestet unter Debian 12 mit Nginx 1.22.1 und PHP 8.2.

Sie öffnen Ihre Website und sehen statt der Seite einen weißen Bildschirm mit der Aufschrift **502 Bad Gateway**, **504 Gateway Time-out**, **403 Forbidden** oder **500 Internal Server Error**. Die Fehlernummer wirkt erschreckend, verrät aber ziemlich genau, an welcher Stelle des Weges vom Browser zur Website etwas kaputtgegangen ist, und die eigentliche Ursache steht in einer einzigen Zeile im Nginx-Protokoll. In diesem Artikel klären wir, wie dieser Weg aufgebaut ist, lernen, die Ursache in ein paar Minuten zu finden, und beheben nacheinander jeden der vier Fehler anhand der Beispiele, die am häufigsten vorkommen. Alle Beispiele haben wir auf einem Testserver mit Debian 12 nachgestellt, die Nginx-Version war zum Zeitpunkt der Prüfung **1.22.1**, PHP **8.2.34**.

***

## Wie der Weg vom Browser zur Website aufgebaut ist

Wenn ein Besucher eine Seite öffnet, schickt sein Browser eine Anfrage an den Webserver, also an Nginx. Wird ein gewöhnliches Bild oder eine fertige HTML-Seite gebraucht, nimmt Nginx einfach die Datei von der Festplatte und liefert sie aus. Die meisten Websites bestehen aber nicht nur aus Dateien. Die Seite muss zusammengebaut werden, zum Beispiel mit einer Abfrage an die Datenbank, und das erledigt ein eigenes Programm, das man **Backend** nennt. Das kann PHP-FPM sein, das die WordPress-Skripte ausführt, oder eine Anwendung in Python oder Node.js, die auf ihrem eigenen Port lauscht. In dieser Kombination arbeitet Nginx als Pförtner. Er nimmt die Anfrage entgegen, reicht sie an das Backend weiter, wartet auf die Antwort und schickt sie an den Browser. Deshalb enthalten zwei der vier Fehler im Namen das Wort „Gateway“, denn in diesem Moment steht Nginx als Übergang zwischen dem Besucher und der Anwendung.

Die erste Ziffer des Codes zeigt, auf wessen Seite der Fehlschlag liegt. Der Code **403** gehört zur Familie 4xx, also zu Anfragen, die in der eingegangenen Form nicht ausgeführt werden können. Nginx hat sehr wohl verstanden, was der Browser will, weigert sich aber, die Antwort auszuliefern, weil es nichts zu zeigen gibt oder ihm die Rechte fehlen, die nötigen Dateien zu lesen. Die Codes der Familie 5xx bedeuten einen Fehler auf der Serverseite. Der Code **500** sagt, dass bei der Verarbeitung der Anfrage etwas kaputtgegangen ist, meistens im Skript oder in der Anwendung selbst. Der Code **502** bedeutet, dass Nginx vom Backend keine brauchbare Antwort bekommen hat, zum Beispiel weil das Backend nicht läuft. Der Code **504** bedeutet, dass das Backend zwar erreichbar ist, aber nicht in der vorgesehenen Zeit geantwortet hat. Bei jedem dieser Fehler müssen Sie deshalb zuerst herausfinden, an welchem Glied der Kette die Verbindung abgerissen ist.

Der Code nennt das Glied, aber nicht die Ursache, und die Ursache müssen Sie im Protokoll suchen. Nehmen wir zum Beispiel an, dass PHP-FPM angehalten wurde. Der Browser wendet sich weiterhin an Nginx, der versucht, die Anfrage an den Socket von PHP-FPM weiterzugeben, sich aber nicht verbinden kann. Deshalb zeigt er selbst eine kurze 502-Seite mit seiner Versionsnummer am unteren Rand an und schreibt ins Protokoll, womit genau er sich nicht verbinden konnte. Läuft PHP-FPM dagegen und das Skript ist mit einem fatalen Fehler abgestürzt, erhält Nginx von ihm eine Antwort mit dem Code 500 und leerem Inhalt und gibt sie unverändert weiter, während die Fehlermeldung dann der Browser selbst zeichnet. Beide Bilder haben wir auf dem Testserver gesehen, und am Aussehen der Seite lässt sich erraten, wer sie ausgegeben hat, Nginx oder die Anwendung. Die genaue Antwort steht dennoch im Fehlerprotokoll, zu dem wir gleich kommen.

***

## Was Sie brauchen

* **Einen Server** mit Debian 12, auf dem Nginx bereits läuft, zum Beispiel den Tarif **DE-RZ9-1**. Die Beispiele im Artikel sind sehr leicht, und welcher Tarif für Ihre Website passt, hilft Ihnen der Artikel über [VPS](https://docs.f3cloud.com/de/vps/cloud-server-types/vps-hosting.md) zu entscheiden. Wenn Sie noch keinen Server haben, bestellen Sie ihn nach der [Anleitung](https://docs.f3cloud.com/de/client-area/order-vps.md).
* **Eine SSH-Verbindung**, zum Beispiel über [Termius](https://docs.f3cloud.com/de/vps/termius-connection.md). Die Befehle werden als `root` ausgeführt.
* **Nginx und PHP-FPM**. Wie Sie beides installieren, haben wir im Artikel über die [Installation von Nginx](https://docs.f3cloud.com/de/web/nginx-installation.md) beschrieben. PHP-FPM brauchen Sie nur für die Beispiele mit PHP.
* **Eine Website oder Anwendung**, auf der Sie den Fehler sehen.

> **Adressen und Namen in den Beispielen.**
>
> Auf dem Testserver lief jedes Beispiel auf einem eigenen Port, deshalb steht in den Befehlen und auf den Terminal-Screenshots statt einer Domain eine Adresse der Form `127.0.0.1:8091`. Auf Ihre Website verweisen Sie über die Domain, zum Beispiel `https://example.com`. Die Ordner `errors-demo-…` und der Dienst `errors-app` sind ebenfalls für den Artikel erfunden, bei Ihnen heißen sie anders. Die Browser-Screenshots stammen von denselben Testwebsites, die Domain `example.com` in der Adresszeile ist fiktiv.

***

## Schritt 1. Ermitteln Sie den Antwortcode

Beginnen Sie mit dem Befehl `curl`. Er greift auf die Website genauso zu wie ein Browser, zeigt aber nur das, was der Server tatsächlich geantwortet hat. Der Parameter `-I` fordert nur die Antwort-Header an, und der Code steht in der allerersten Zeile.

```bash
# Antwort-Header anzeigen, in der ersten Zeile steht der Code
curl -I https://example.com
```

Wenn Sie nur die Zeile mit dem Code brauchen, fügen Sie den Parameter `-s` hinzu und leiten Sie die Ausgabe an den Befehl `head` weiter.

```bash
# Nur die erste Zeile der Antwort
curl -sI https://example.com | head -1
```

Eine Zeile wie `HTTP/1.1 502 Bad Gateway` bestätigt, dass der Fehler vom Server kam und nicht von Ihrem Netzwerk oder Browser. Außerdem ist im Header `Server` die Nginx-Version zu sehen.

***

## Schritt 2. Lesen Sie das Fehlerprotokoll von Nginx

Jede Ablehnung schreibt Nginx in die Datei `/var/log/nginx/error.log`. Öffnen Sie das Protokoll im Beobachtungsmodus und aktualisieren Sie dann im Browser die Seite mit dem Fehler. Die neue Zeile erscheint im selben Moment.

```bash
# Protokoll live verfolgen, Beenden mit Ctrl+C
tail -f /var/log/nginx/error.log
```

> **Alte Zeilen stören nicht.**
>
> Der Befehl `tail -f` zeigt zuerst die letzten zehn Zeilen des Protokolls und wartet erst danach auf neue. Damit alte Einträge nicht ablenken, fügen Sie den Parameter `-n 0` hinzu, wie auf dem Screenshot unten.

<figure><img src="https://docs.f3cloud.com/img/errors-diagnosis.png" alt="Der Befehl curl -I zeigt 502 Bad Gateway, und tail -f gibt die Zeile connect() failed (111: Connection refused) aus error.log aus"><figcaption><p>Der Antwortcode und die Zeile aus dem Protokoll, die die Ursache erklärt</p></figcaption></figure>

Eine solche Zeile lässt sich leicht auseinandernehmen. Nehmen wir die, die wir erhalten haben, als die Anwendung hinter Nginx angehalten war.

```text
2026/10/21 14:53:33 [error] 124894#124894: *3 connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: example.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8098/", host: "example.com"
```

* **Uhrzeit und Schweregrad** am Anfang der Zeile. Das Wort in eckigen Klammern zeigt den Schweregrad des Eintrags, bei uns kamen `[error]` und `[crit]` vor.
* **Kern des Problems** gleich nach der Prozessnummer. Hier ist das `connect() failed (111: Connection refused)`, also konnte Nginx sich nicht verbinden, weil der Port geschlossen ist.
* **client** zeigt, wer die Anfrage gestellt hat, **server** und **host** zeigen, an welche Website, und **request** enthält die Anfrage selbst.
* **upstream** zeigt, wohin genau Nginx die Anfrage weitergeben wollte. Das ist die Adresse des Backends, und sie verrät, welches Programm Sie als Nächstes prüfen sollten.

Das Protokoll ist für alle Websites auf dem Server gemeinsam, deshalb suchen Sie bei viel Traffic den gewünschten Eintrag am besten anhand der Seitenadresse.

```bash
# Letzte Einträge, in denen die gesuchte Adresse vorkommt
grep '/slow' /var/log/nginx/error.log | tail -n 5
```

Mehr darüber, wie man Logs liest und wo sie liegen, steht im Artikel über [Logs unter Linux](https://docs.f3cloud.com/de/linux/linux-logs.md).

***

## Schritt 3. Prüfen Sie das Programm hinter Nginx

Wenn in der Protokollzeile das Wort `upstream` steht, müssen Sie als Nächstes klären, was mit dem Backend los ist. Für eine Anwendung, die als systemd-Dienst läuft, prüfen Sie den Zustand und die letzten Meldungen. Setzen Sie statt `myapp` den Namen Ihres Dienstes ein, bei PHP ist das `php8.2-fpm`.

```bash
# Zustand des Dienstes
systemctl status myapp --no-pager

# Letzte 50 Meldungen des Dienstes
journalctl -u myapp -n 50 --no-pager

# Wer lauscht auf dem gewünschten Port, setzen Sie statt 8098 Ihren eigenen ein
ss -tlnp | grep 8098
```

In der Zeile **Active** sollte `active (running)` stehen. Die Werte `failed` und `inactive (dead)` bedeuten, dass das Programm angehalten hat, und die Ursache nennt in der Regel das Protokoll des Dienstes. Der letzte Befehl zeigt die Programme, die auf Ports lauschen. Eine leere Ausgabe heißt, dass auf diesem Port niemand lauscht und Nginx niemanden hat, an den er Anfragen weitergeben kann. Wie Sie Dienste verwalten und ihre Logs lesen, ist ausführlich im Artikel über [systemd-Dienste](https://docs.f3cloud.com/de/linux/systemd-services.md) beschrieben.

<figure><img src="https://docs.f3cloud.com/img/errors-502-app-failed.png" alt="systemctl status zeigt failed, journalctl zeigt FileNotFoundError, der Befehl ss findet nichts auf Port 8098"><figcaption><p>Der Dienst ist im Zustand failed, im Protokoll steht die Ursache, auf Port 8098 lauscht niemand</p></figcaption></figure>

Auf dem Screenshot ist der Dienst `errors-app` gleich nach dem Start abgestürzt. Im Protokoll ist die Ursache zu sehen, `FileNotFoundError`, also fehlte der Anwendung die Konfigurationsdatei. Mit der Fehlernummer und der Zeile aus dem Protokoll können Sie zur Analyse der konkreten Ursache übergehen.

***

## Fehler 502 Bad Gateway

Die Seite 502 bedeutet, dass Nginx die Anfrage angenommen hat, aber keine Antwort vom Backend bekommen konnte. Sie sieht aus wie eine kurze weiße Seite mit der Nginx-Versionsnummer am unteren Rand.

<figure><img src="https://docs.f3cloud.com/img/errors-502-browser.png" alt="Seite 502 Bad Gateway mit der Aufschrift nginx/1.22.1"><figcaption><p>So sieht der Fehler 502 im Browser aus</p></figcaption></figure>

Wir haben die drei häufigsten Ursachen nachgestellt, und jede hinterlässt im Protokoll eine eigene Zeile.

### Die Anwendung läuft nicht

Das ist die einfachste und häufigste Ursache. In den Nginx-Einstellungen gibt die Website Anfragen an die Anwendung weiter.

```nginx
location / {
    proxy_pass http://127.0.0.1:8098;
}
```

Wenn die Anwendung angehalten wurde, abgestürzt ist oder nach einem Neustart des Servers nie gestartet wurde, lauscht auf ihrem Port niemand. Das Protokoll enthält dann die schon bekannte Zeile.

```text
2026/10/21 14:53:33 [error] 124894#124894: *3 connect() failed (111: Connection refused) while connecting to upstream, client: 127.0.0.1, server: example.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8098/", host: "example.com"
```

Der Code `111: Connection refused` bedeutet wörtlich, dass die Verbindung abgelehnt wurde, weil der Port geschlossen ist. In unserem Beispiel hat die Ursache das Protokoll des Dienstes gezeigt, das Sie auf dem Screenshot oben gesehen haben. Die Anwendung ist nicht gestartet, weil wir ihre Konfigurationsdatei umbenannt hatten. Legen Sie die Datei zurück und starten Sie den Dienst.

```bash
# Konfigurationsdatei an ihren Platz zurücklegen
mv /opt/errors-demo/config.json.old /opt/errors-demo/config.json

# Dienst starten und die Antwort der Website prüfen
systemctl start errors-app
curl -I http://127.0.0.1:8091
```

<figure><img src="https://docs.f3cloud.com/img/errors-502-app-fixed.png" alt="Nach dem Start des Dienstes liefert curl -I 200 OK, und curl zeigt die Antwort der Anwendung"><figcaption><p>Der Dienst läuft, die Website antwortet wieder mit dem Code 200</p></figcaption></figure>

Damit sich ein solcher Fehler nicht nach jedem Absturz wiederholt, überlassen Sie es systemd, die Anwendung selbst wieder hochzufahren. Fügen Sie dazu in der Dienstdatei zwei Zeilen im Abschnitt `[Service]` hinzu.

```ini
[Service]
# Anwendung neu starten, wenn sie abgestürzt ist
Restart=on-failure
# Vor dem Neustart drei Sekunden warten
RestartSec=3
```

Laden Sie danach die Einstellungen neu und aktivieren Sie den Autostart beim Start des Servers.

```bash
# Änderungen in der Dienstdatei übernehmen
systemctl daemon-reload

# Start zusammen mit dem Server aktivieren
systemctl enable errors-app
```

Die Prüfung war anschaulich. Wir haben den Prozess mit dem Befehl `systemctl kill -s KILL errors-app` zwangsweise beendet. Gleich danach antwortete die Website mit dem Code 502, und nach drei Sekunden startete systemd die Anwendung neu und die Website öffnete sich wieder. Beachten Sie, dass vor dem Aktivieren des Autostarts in der Zeile **Loaded** auf dem Screenshot das Wort `disabled` stand. Es bedeutet, dass der Dienst nach einem Neustart des Servers nicht von selbst startet.

### PHP-FPM, Socket nicht gefunden

Bei PHP-Websites gibt Nginx Anfragen nicht an einen Port weiter, sondern an einen Socket, also eine spezielle Datei, über die er mit PHP-FPM kommuniziert. Der Pfad dazu steht in der Direktive `fastcgi_pass`.

```nginx
location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
```

Gibt es diese Datei nicht, antwortet Nginx mit 502, und das Protokoll sagt das im Klartext.

```text
2026/10/21 14:53:33 [crit] 124894#124894: *5 connect() to unix:/run/php/php8.1-fpm.sock failed (2: No such file or directory) while connecting to upstream, client: 127.0.0.1, server: example.com, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.1-fpm.sock:", host: "example.com"
```

Der Code `2: No such file or directory` bedeutet, dass die Socket-Datei nicht existiert. Meist gibt es zwei Ursachen. Entweder steht in den Einstellungen der Name einer anderen PHP-Version, zum Beispiel aus einer Anleitung für PHP 8.1, während bei Ihnen 8.2 installiert ist, oder der Dienst PHP-FPM ist angehalten, und sein Socket ist mit ihm verschwunden. Sehen Sie nach, welche Sockets es auf dem Server gibt.

```bash
# Liste der PHP-FPM-Sockets
ls /run/php/
```

<figure><img src="https://docs.f3cloud.com/img/errors-502-php-socket.png" alt="curl zeigt 502, in error.log steht php8.1-fpm.sock failed (2: No such file or directory), und im Ordner /run/php liegt php8.2-fpm.sock"><figcaption><p>In den Einstellungen steht php8.1-fpm.sock, auf dem Server gibt es aber nur php8.2-fpm.sock</p></figcaption></figure>

In unserem Beispiel lagen im Ordner `php8.2-fpm.sock` und `php-fpm.sock`. Korrigieren Sie den Namen in `fastcgi_pass`, prüfen Sie die Einstellungen und wenden Sie sie an.

```bash
# Version im Socket-Namen ändern
sed -i 's/php8.1-fpm.sock/php8.2-fpm.sock/' /etc/nginx/sites-available/example.com

# Einstellungen prüfen und anwenden
nginx -t && systemctl reload nginx
```

> **Die Datei php-fpm.sock.**
>
> Unter Debian liegt neben dem Socket der jeweiligen Version noch `php-fpm.sock`. Das ist ein Link auf den Socket der installierten PHP-Version, und auf unserem Server führte er zu `php8.2-fpm.sock`. Wenn Sie in `fastcgi_pass` genau ihn angeben, müssen Sie den Namen in den Einstellungen beim Wechsel der PHP-Version nicht ändern. Wir haben geprüft, dass die Website mit einem solchen Pfad normal antwortet.

Stimmt der Name, der Socket fehlt aber trotzdem, ist PHP-FPM selbst angehalten. Wir haben ihn mit dem Befehl `systemctl stop php8.2-fpm` gestoppt und denselben Fehler 502 mit der Zeile `connect() to unix:/run/php/php8.2-fpm.sock failed (2: No such file or directory)` erhalten. Der Befehl `systemctl status php8.2-fpm` zeigte `inactive (dead)`, und nach dem Start des Dienstes funktionierte die Website wieder.

<figure><img src="https://docs.f3cloud.com/img/errors-502-php-stopped.png" alt="Nach dem Stoppen von php8.2-fpm antwortet die Website mit 502, im Protokoll fehlt die Socket-Datei, systemctl status zeigt inactive (dead), nach dem Start funktioniert die Website"><figcaption><p>PHP-FPM ist gestoppt, der Socket fehlt, nach dem Start des Dienstes öffnet sich die Website wieder</p></figcaption></figure>

Startet der Dienst nicht, zeigt `journalctl -u php8.2-fpm -n 50 --no-pager` die Ursache. Und nach Änderungen an den PHP-FPM-Einstellungen prüfen Sie diese mit dem Befehl `php-fpm8.2 -t`, wie wir weiter unten zeigen.

### PHP-FPM, kein Zugriff auf den Socket

Manchmal ist der Socket vorhanden, aber Nginx kann ihn nicht nutzen. Im Protokoll steht dann ein anderer Code.

```text
2026/10/21 14:57:38 [crit] 133790#133790: *56 connect() to unix:/run/php/errors-fpm.sock failed (13: Permission denied) while connecting to upstream, client: 127.0.0.1, server: example.com, request: "HEAD / HTTP/1.1", upstream: "fastcgi://unix:/run/php/errors-fpm.sock:", host: "127.0.0.1:8099"
```

<figure><img src="https://docs.f3cloud.com/img/errors-502-sock-denied.png" alt="curl liefert 502, im Protokoll connect() to unix:/run/php/errors-fpm.sock failed (13: Permission denied), ls zeigt root als Besitzer der Socket-Datei"><figcaption><p>Der Socket ist vorhanden, gehört aber root, und Nginx kann sich nicht mit ihm verbinden</p></figcaption></figure>

Der Code `13: Permission denied` bedeutet, dass Nginx keine Rechte für diese Datei hat. Nginx läuft unter dem Benutzer `www-data`, und den Zugriff auf den Socket bestimmen die Parameter `listen.owner`, `listen.group` und `listen.mode` in den Einstellungen des PHP-FPM-Pools. Laut PHP-Dokumentation erhält der Socket, wenn kein Besitzer angegeben ist, den Benutzer, unter dem der Dienst gestartet wurde, und die Rechte `0660`. In unserem Beispiel haben wir einen eigenen Pool `errors` in der Datei `/etc/php/8.2/fpm/pool.d/errors.conf` angelegt und keinen Besitzer angegeben.

```ini
[errors]
user = nobody
group = nogroup
listen = /run/php/errors-fpm.sock
pm = ondemand
pm.max_children = 2
pm.process_idle_timeout = 10s
```

Der Dienst läuft als `root`, deshalb erhielt der Socket den Besitzer `root` und die Rechte `srw-rw----`, und `www-data` gehört nicht zu dieser Gruppe. Fügen Sie dem Pool zwei Zeilen mit dem Besitzer hinzu.

```bash
# In den Ordner mit den Pool-Einstellungen wechseln
cd /etc/php/8.2/fpm/pool.d

# Dem Nginx-Benutzer die Arbeit mit dem Socket erlauben
printf 'listen.owner = www-data\nlisten.group = www-data\n' >> errors.conf

# Einstellungen prüfen und PHP-FPM neu starten
php-fpm8.2 -t && systemctl restart php8.2-fpm

# Besitzer des Sockets ansehen und die Website prüfen
ls -l /run/php/errors-fpm.sock
curl http://127.0.0.1:8099/
```

<figure><img src="https://docs.f3cloud.com/img/errors-502-sock-fixed.png" alt="Nach dem Hinzufügen von listen.owner und listen.group gehört der Socket www-data, curl liefert die Antwort von PHP"><figcaption><p>Der Socket gehört www-data, die Website antwortet</p></figcaption></figure>

> **Hier hilft nur ein restart.**
>
> Als wir nach der Änderung `systemctl reload php8.2-fpm` ausgeführt haben, blieb der Besitzer des Sockets derselbe, `root`, und der Fehler 502 verschwand nicht. Den Besitzer wechselte der Socket erst nach `systemctl restart php8.2-fpm`.

> **Prüfen Sie die Einstellungen immer vor dem Neuladen.**
>
> Gewöhnen Sie sich an, vor jedem Befehl `reload` auch `nginx -t` auszuführen. Steckt in den Einstellungen ein Fehler, zeigt ihn die Prüfung an, und der laufende Nginx antwortet weiter mit der alten Konfiguration. Für PHP-FPM gibt es dieselbe Prüfung, den Befehl `php-fpm8.2 -t`.

***

## Fehler 504 Gateway Time-out

Die Seite 504 besagt, dass das Backend lebt und die Anfrage angenommen hat, aber zu lange an der Antwort arbeitet. Nginx wartet darauf nur begrenzte Zeit und bricht das Warten, wenn nichts kommt, selbst ab. Die Wartezeit legt die Direktive `proxy_read_timeout` fest, standardmäßig sind das 60 Sekunden, und für PHP-FPM übernimmt `fastcgi_read_timeout` dieselbe Rolle. Ein wichtiges Detail aus der Nginx-Dokumentation ist, dass diese Zeit zwischen zwei aufeinanderfolgenden Lesevorgängen gezählt wird und nicht für die gesamte Antwort. Schickt das Backend den nächsten Datenabschnitt öfter als alle 60 Sekunden, reißt die Verbindung nicht ab.

Um das mit eigenen Augen zu sehen, haben wir der Testanwendung die Adresse `/slow` hinzugefügt, die erst nach 75 Sekunden antwortet, wie ein aufwendiger Bericht oder eine lange Datenbankabfrage. Die Seite lud genau eine Minute lang, dann erschien der Fehler.

<figure><img src="https://docs.f3cloud.com/img/errors-504-browser.png" alt="Seite 504 Gateway Time-out mit der Aufschrift nginx/1.22.1"><figcaption><p>Der Fehler 504 erscheint nach einer Minute Wartezeit</p></figcaption></figure>

Mit dem Parameter `-w` kann der Befehl `curl` die Zeit messen und den Code auf einen Blick zeigen.

```bash
# Antwortcode und Wartezeit anzeigen
curl -s -o /dev/null -w '%{http_code} nach %{time_total} s\n' http://127.0.0.1:8093/slow
```

Im Protokoll erschien dabei dieser Eintrag.

```text
2026/10/21 15:04:14 [error] 144934#144934: *81 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 127.0.0.1, server: example.com, request: "GET /slow HTTP/1.1", upstream: "http://127.0.0.1:8098/slow", host: "127.0.0.1:8093"
```

<figure><img src="https://docs.f3cloud.com/img/errors-504-log.png" alt="curl liefert 504 nach 60 Sekunden, in error.log steht upstream timed out (110: Connection timed out) while reading response header from upstream"><figcaption><p>Der Code 504 nach 60,06 Sekunden und die Zeile upstream timed out im Protokoll</p></figcaption></figure>

Die Wörter `while reading response header` bedeuten, dass Nginx sich erfolgreich verbunden, die Anfrage gesendet und auf den Beginn der Antwort gewartet hat. Die Messung ergab 60,06 Sekunden, Nginx hat das Warten also genau nach dem Standardwert abgebrochen.

Einen 504 behebt man am besten an der Ursache. Finden Sie heraus, was genau lange dauert, zum Beispiel eine aufwendige Datenbankabfrage, der Zugriff auf einen fremden Dienst oder ein großer Bericht, und beschleunigen Sie es. Ist die Aufgabe von Natur aus langwierig, zum Beispiel ein Export oder Import, erhöhen Sie die Wartezeit für die betreffende Adresse. Fügen Sie dem Block `location` die Direktive `proxy_read_timeout` hinzu.

```nginx
location / {
    proxy_pass http://127.0.0.1:8098;
    # Auf die Antwort der Anwendung bis zu zwei Minuten warten
    proxy_read_timeout 120s;
}
```

Prüfen Sie die Einstellungen, wenden Sie sie an und wiederholen Sie dann die Anfrage.

```bash
# Einstellungen prüfen und anwenden
nginx -t && systemctl reload nginx

# Anfrage wiederholen
curl -s -o /dev/null -w '%{http_code} nach %{time_total} s\n' http://127.0.0.1:8093/slow
```

<figure><img src="https://docs.f3cloud.com/img/errors-504-fixed.png" alt="Nach proxy_read_timeout 120s liefert dieselbe Anfrage 200 nach 75 Sekunden"><figcaption><p>Dieselbe Anfrage liefert jetzt 200 nach 75 Sekunden</p></figcaption></figure>

Bei Websites mit PHP-FPM gehen Sie genauso vor, nur heißt die Direktive `fastcgi_read_timeout` und steht im Block `location ~ \.php$` neben `fastcgi_pass`. Wir haben das an einem Skript geprüft, das nach 70 Sekunden antwortet. Mit den Standardeinstellungen lieferte es genau nach 60 Sekunden einen 504, und mit der Zeile `fastcgi_read_timeout 120s;` antwortete es nach 70 Sekunden mit dem Code 200. Die Zeile im Protokoll sah dabei so aus.

```text
2026/10/21 15:07:46 [error] 153814#153814: *89 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 127.0.0.1, server: example.com, request: "GET /slow.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock", host: "127.0.0.1:8096"
```

> **Das Nginx-Timeout hebt das PHP-Limit nicht auf.**
>
> PHP hat eine eigene Obergrenze für die Laufzeit eines Skripts, den Parameter `max_execution_time`. In der Datei `/etc/php/8.2/fpm/php.ini` beträgt er auf unserem Server 30 Sekunden. Wir haben ein Skript gestartet, das ununterbrochen den Prozessor auslastete, und PHP stoppte es genau nach 30 Sekunden. Als Antwort kam kein 504, sondern der Fehler 500, und im Protokoll erschien die Zeile `PHP Fatal error: Maximum execution time of 30 seconds exceeded in /var/www/errors-demo-php/busy.php on line 3`. Ein Skript, das einfach mit dem Aufruf `sleep(70)` wartete, fiel nicht unter diese Beschränkung, weil laut PHP-Dokumentation die Wartezeit von Systemaufrufen unter Linux nicht mitgezählt wird. Stößt Ihr Skript genau an das PHP-Limit, erhöhen Sie `max_execution_time` und nicht nur das Timeout von Nginx.

***

## Fehler 403 Forbidden

Die Seite 403 bedeutet, dass Nginx die Anfrage verstanden hat, sich aber weigert, sie zu beantworten. In der Praxis gibt es zwei Ursachen. Entweder gibt es im Ordner nichts zu zeigen, oder Nginx hat keine Rechte, die Datei zu lesen. Im Protokoll lassen sich diese Fälle leicht unterscheiden, beginnen Sie deshalb immer dort.

<figure><img src="https://docs.f3cloud.com/img/errors-403-browser.png" alt="Seite 403 Forbidden mit der Aufschrift nginx/1.22.1"><figcaption><p>So sieht der Fehler 403 im Browser aus</p></figcaption></figure>

### Keine Indexdatei

Wenn ein Besucher die Adresse eines Ordners öffnet, zum Beispiel `https://example.com/`, sucht Nginx darin die Startseite. Den Dateinamen legt die Direktive `index` fest, standardmäßig ist das `index.html`. Gibt es eine solche Datei nicht, könnte Nginx die Dateiliste des Ordners anzeigen, aber standardmäßig ist das abgeschaltet (`autoindex off`), und deshalb antwortet er mit 403.

```text
2026/10/21 14:53:33 [error] 124894#124894: *7 directory index of "/var/www/errors-demo-403a/" is forbidden, client: 127.0.0.1, server: example.com, request: "GET / HTTP/1.1", host: "example.com"
```

Die Formulierung `directory index of … is forbidden` bedeutet genau, dass im Ordner keine Indexdatei liegt und die Dateiliste verboten ist. Sehen Sie nach, was im Ordner der Website liegt.

```bash
# Inhalt des Website-Ordners anzeigen
ls -la /var/www/errors-demo-403a
```

<figure><img src="https://docs.f3cloud.com/img/errors-403-noindex.png" alt="curl liefert 403, im Protokoll directory index of /var/www/errors-demo-403a/ is forbidden, und ls zeigt einen leeren Ordner"><figcaption><p>Im Website-Ordner gibt es keine Startseite, deshalb antwortet Nginx mit 403</p></figcaption></figure>

Der Ordner war leer. Meist passiert das, wenn die Website in den falschen Ordner hochgeladen oder die Datei der Startseite selbst vergessen wurde. Prüfen Sie, dass die Direktive `root` auf den Ordner zeigt, in dem die Website tatsächlich liegt, und dass dort eine Datei mit dem Namen aus der Direktive `index` vorhanden ist. Ist das bei einer PHP-Website `index.php`, stellen Sie sicher, dass sie in `index index.html index.php;` angegeben ist. Nach dem Hochladen der Datei ändert sich die Antwort sofort, Nginx müssen Sie nicht neu laden.

```bash
# Startseite anlegen
echo '<h1>Website funktioniert</h1>' > /var/www/errors-demo-403a/index.html

# Antwort prüfen
curl -sI http://127.0.0.1:8094/ | head -1
```

Danach antwortete der Server mit `HTTP/1.1 200 OK`.

Brauchen Sie ausdrücklich eine Dateiliste, zum Beispiel für einen Ordner mit Archiven, schalten Sie sie mit der Direktive `autoindex on;` im gewünschten Block `location` ein. Wir haben geprüft, dass Nginx in diesem Fall die Seite `Index of /` mit der Liste der Dateien im Ordner ausliefert.

> **Die Dateiliste sehen alle.**
>
> Bei `autoindex on` sieht jeder Besucher die Namen aller Dateien im Ordner und kann jede davon herunterladen. Schalten Sie sie nur für Ordner ein, die Sie vollständig zeigen möchten.

### Keine Rechte für die Datei

Im zweiten Fall liegt die Datei am richtigen Platz, aber Nginx kann sie nicht lesen. Das Protokoll meldet das so.

```text
2026/10/21 14:53:33 [error] 124894#124894: *8 open() "/var/www/errors-demo-403b/index.html" failed (13: Permission denied), client: 127.0.0.1, server: example.com, request: "GET / HTTP/1.1", host: "example.com"
```

Der Code `13: Permission denied` bedeutet eine Zugriffsverweigerung auf der Ebene von Linux. Um zu verstehen, auf wessen Rechte es ankommt, finden Sie heraus, unter welchem Benutzer Nginx läuft, und sehen Sie sich dann mit dem Befehl `namei` die Rechte für jedes Element des Pfades an.

```bash
# Unter welchem Benutzer Nginx läuft
grep ^user /etc/nginx/nginx.conf

# Rechte für jeden Ordner und jede Datei auf dem Pfad
namei -l /var/www/errors-demo-403b/index.html
```

<figure><img src="https://docs.f3cloud.com/img/errors-403-perm.png" alt="Im Protokoll open() index.html failed (13: Permission denied), in nginx.conf user www-data, namei zeigt bei der Datei index.html die Rechte -rw------- root root"><figcaption><p>Nginx läuft unter www-data, und die Datei ist für alle außer root gesperrt</p></figcaption></figure>

Nginx läuft unter `www-data`, und die Datei hat die Rechte `-rw-------` und gehört `root`, also kann nur der Besitzer sie lesen. Für `www-data` ist das ein fremder Benutzer, und er hat keinen Zugriff. Dieses Bild haben wir erhalten, indem wir die Datei als `root` mit den Rechten `600` angelegt haben. Für eine Website gilt eine einfache Regel. Ordner erhalten `755`, Dateien `644`, und als Besitzer wird der Benutzer des Webservers eingetragen. Wie Rechte aufgebaut sind und was diese Zahlen bedeuten, steht im Artikel über [Zugriffsrechte unter Linux](https://docs.f3cloud.com/de/linux/linux-permissions.md).

```bash
# Die Website an den Benutzer des Webservers übergeben
chown -R www-data:www-data /var/www/errors-demo-403b

# Ordner 755, Dateien 644
find /var/www/errors-demo-403b -type d -exec chmod 755 {} +
find /var/www/errors-demo-403b -type f -exec chmod 644 {} +
```

<figure><img src="https://docs.f3cloud.com/img/errors-403-perm-fixed.png" alt="Nach chown und chmod hat die Datei index.html die Rechte -rw-r--r-- und den Besitzer www-data, curl liefert 200 OK"><figcaption><p>Die Datei ist lesbar, die Website antwortet mit dem Code 200</p></figcaption></figure>

Zum Lesen der Datei genügt Nginx das Recht `r` für „Andere“. Wir haben geprüft, dass die Website auch mit dem Besitzer `root` und den Rechten `644` aufgerufen werden kann, und der Wechsel des Besitzers ist nötig, damit die Website hochgeladene Dateien selbst speichern kann.

> **Beheben Sie 403 nicht mit den Rechten 777.**
>
> Die Rechte `777` erlauben allen Benutzern des Servers, die Datei zu lesen und zu ändern, und der Fehler verschwindet tatsächlich. Mit ihm verschwindet aber auch der Schutz der Website, deshalb sollten Sie einen solchen Ratschlag aus dem Internet besser nicht befolgen. Machen Sie den Benutzer `www-data` zum Besitzer und setzen Sie `755` und `644`.

### Keine Rechte für einen Ordner auf dem Weg zur Datei

Manchmal ist die Datei selbst für alle zugänglich, und der Fehler bleibt trotzdem bestehen. Um die Datei zu erreichen, muss Nginx jeden Ordner auf dem Pfad durchlaufen, und dafür braucht `www-data` auf jedem davon das Recht `x`. Es genügt, dass ein einziger Ordner gesperrt ist. Das Protokoll sieht in diesem Fall etwas anders aus, es enthält nicht das Wort `open()`.

```text
2026/10/21 15:08:10 [error] 156517#156517: *109 "/var/www/errors-demo-403c/public/index.html" is forbidden (13: Permission denied), client: 127.0.0.1, server: example.com, request: "GET / HTTP/1.1", host: "127.0.0.1:8095"
```

In unserem Beispiel hat die Datei `index.html` die Rechte `644`, aber der Ordner darüber ist gesperrt. Beim Finden hilft derselbe Befehl `namei`.

```bash
# Den gesperrten Ordner auf dem Pfad zur Datei suchen
namei -l /var/www/errors-demo-403c/public/index.html
```

<figure><img src="https://docs.f3cloud.com/img/errors-403-dir.png" alt="namei zeigt beim Ordner errors-demo-403c die Rechte drwx------, nach chmod 755 antwortet die Website mit 200 OK"><figcaption><p>Der Ordner errors-demo-403c ist für alle außer root gesperrt, nach chmod 755 öffnet sich die Website</p></figcaption></figure>

In der Ausgabe hat der Ordner `errors-demo-403c` die Rechte `drwx------`, die übrigen Ordner sind offen. Öffnen Sie ihn zum Lesen und Betreten.

```bash
# Allen Benutzern erlauben, den Ordner zu betreten
chmod 755 /var/www/errors-demo-403c
```

Ein solches Bild ist typisch für Websites, die in einem gesperrten Ordner liegen, zum Beispiel im Home-Verzeichnis. Auf unserem Server hat der Ordner `/root` die Rechte `700`, deshalb sollten Sie eine Website dort nicht ablegen. Verwenden Sie für Websites `/var/www`.

***

## Fehler 500 Internal Server Error

Der Code 500 gilt als der unbestimmteste, denn er bedeutet einfach „bei der Verarbeitung der Anfrage ist etwas schiefgegangen“. Deshalb ist es hier besonders wichtig, ins Protokoll zu schauen. Wir haben zwei Ursachen nachgestellt, die häufiger vorkommen als andere. Die erste betrifft PHP, die zweite Nginx selbst.

### Fataler Fehler in PHP

Stürzt ein PHP-Skript ab, antwortet PHP-FPM mit dem Code 500. Standardmäßig zeigt PHP dem Besucher den Fehlertext nicht, und in unserem Fall war der Parameter `display_errors` in `/etc/php/8.2/fpm/php.ini` ausgeschaltet und `log_errors` eingeschaltet. Der Inhalt der Antwort war leer, deshalb hat die Aufschrift der Browser selbst gezeichnet und nicht Nginx.

<figure><img src="https://docs.f3cloud.com/img/errors-500-php-browser.png" alt="Eigene Fehlerseite des Browsers mit der Aufschrift HTTP ERROR 500"><figcaption><p>Bei einer leeren Antwort zeigt der Browser seine eigene Seite mit dem Code HTTP ERROR 500</p></figcaption></figure>

Dafür landet alles, was PHP sagen wollte, im Protokoll von Nginx.

```text
2026/10/21 15:09:26 [error] 156517#156517: *123 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function mb_strlen() in /var/www/errors-demo-php/page.php:3
Stack trace:
#0 {main}
  thrown in /var/www/errors-demo-php/page.php on line 3" while reading response header from upstream, client: 127.0.0.1, server: example.com, request: "GET /page.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock:", host: "127.0.0.1:8096"
```

<figure><img src="https://docs.f3cloud.com/img/errors-500-php-log.png" alt="curl liefert 500, in error.log der Eintrag FastCGI sent in stderr PHP Fatal error Call to undefined function mb_strlen()"><figcaption><p>Der Code 500 und die Zeile aus dem Protokoll mit dem PHP-Fehlertext</p></figcaption></figure>

Der Eintrag beginnt mit den Worten `FastCGI sent in stderr`, danach folgt die PHP-Meldung selbst. Lesen müssen Sie sie so. Der Fehlertyp `PHP Fatal error`, dann der Kern, `Call to undefined function mb_strlen()`, es wurde also eine Funktion aufgerufen, die es nicht gibt, und am Ende die Datei und die Zeile, in der das geschah. In unserem Beispiel gehört die Funktion `mb_strlen()` zum Modul **mbstring**, das bei einer frischen PHP-Installation fehlt. Dieses Modul steht auf der Liste, die wir im Artikel über die [Installation von Nginx](https://docs.f3cloud.com/de/web/nginx-installation.md) für WordPress empfehlen. Installieren Sie das fehlende Modul.

```bash
# Modul mbstring für PHP installieren
apt install -y php-mbstring
```

Nach der Installation haben wir nichts neu gestartet, und die Seite funktionierte sofort.

<figure><img src="https://docs.f3cloud.com/img/errors-500-php-fixed.png" alt="Nach apt install php-mbstring liefert die Seite 200 OK und die Zahl 11"><figcaption><p>Das Modul ist installiert, die Seite liefert 200 und das Ergebnis der Funktion</p></figcaption></figure>

Eine weitere häufige Ursache für 500 in PHP ist ein Syntaxfehler nach dem Bearbeiten einer Datei. Eine Datei können Sie auf dem Server mit dem Befehl `php -l` prüfen, und er sagt auch, in welcher Zeile der Fehler steht.

```bash
# Syntax der Datei prüfen
php -l /var/www/errors-demo-php/parse.php
```

```text
PHP Parse error:  syntax error, unexpected token "echo", expecting "," or ";" in parse.php on line 3
Errors parsing parse.php
```

> **Schalten Sie die Fehleranzeige auf einer produktiven Website nicht ein.**
>
> Den Parameter `display_errors` können Sie einschalten, um den Fehler direkt im Browser zu sehen, aber auf einer produktiven Website sollten Sie das nicht tun. Der Fehlertext enthält Pfade zu Dateien auf dem Server, und jeder Besucher sieht ihn. Das Nginx-Protokoll liefert dieselben Informationen, aber nur Ihnen.

### Zyklus interner Weiterleitungen

Die zweite Ursache hat mit der Anwendung gar nichts zu tun, es ist ein Fehler in den Einstellungen von Nginx selbst. Betrachten wir eine Einstellung, bei der für jede Adresse, zu der es keine passende Datei gibt, die Startseite `/index.html` ausgeliefert wird.

```nginx
root /var/www/errors-demo-cycle;

location / {
    try_files $uri /index.html;
}
```

Der letzte Parameter von `try_files` funktioniert wie eine interne Weiterleitung. Nginx beginnt die Verarbeitung noch einmal, jetzt für die Adresse `/index.html`, und landet wieder im selben `location`. Existiert die Datei `index.html`, endet alles erfolgreich. Gibt es sie nicht, zum Beispiel weil man vergessen hat, den Build der Website hochzuladen, oder `root` falsch zeigt, leitet Nginx die Anfrage wieder auf `/index.html` um, und so immer im Kreis. Laut Nginx-Dokumentation wird ein solcher Zyklus nach zehn Versuchen abgebrochen, und der Client erhält den Fehler 500.

<figure><img src="https://docs.f3cloud.com/img/errors-500-cycle-browser.png" alt="Seite 500 Internal Server Error mit der Aufschrift nginx/1.22.1"><figcaption><p>Hier hat Nginx den Fehler 500 selbst gezeichnet, deshalb ist unten seine Version zu sehen</p></figcaption></figure>

Im Protokoll sagt der Eintrag das direkt.

```text
2026/10/21 14:53:33 [error] 124894#124894: *11 rewrite or internal redirection cycle while internally redirecting to "/index.html", client: 127.0.0.1, server: example.com, request: "GET / HTTP/1.1", host: "example.com"
```

Die Formulierung `rewrite or internal redirection cycle` bedeutet eine zyklische Weiterleitung, und in Anführungszeichen steht die Adresse, auf die Nginx im Kreis gelaufen ist. Prüfen Sie, ob eine solche Datei im Ordner liegt, der in `root` angegeben ist, und laden Sie sie bei Bedarf hoch.

```bash
# Nachsehen, was im Website-Ordner liegt
ls -la /var/www/errors-demo-cycle

# Datei an ihren Platz legen
echo '<h1>Website funktioniert</h1>' > /var/www/errors-demo-cycle/index.html

# Antwort prüfen
curl -sI http://127.0.0.1:8097/ | head -1
```

<figure><img src="https://docs.f3cloud.com/img/errors-500-cycle.png" alt="curl liefert 500, im Protokoll rewrite or internal redirection cycle while internally redirecting to /index.html, nach dem Anlegen von index.html die Antwort 200 OK"><figcaption><p>Der Zyklus endet, sobald die benötigte Datei im Website-Ordner liegt</p></figcaption></figure>

Nach dem Anlegen der Datei lautete die Antwort `HTTP/1.1 200 OK`. Nginx musste dafür nicht neu geladen werden, denn korrigiert werden musste nicht die Konfiguration, sondern der Inhalt des Ordners.

***

## Häufige Fragen

<details>

<summary>upstream prematurely closed connection while reading response header from upstream</summary>

Diese Zeile im Protokoll begleitet den Fehler 502. Nginx hat sich mit der Anwendung verbunden und die Anfrage gesendet, aber die Anwendung hat die Verbindung abgebrochen, ohne eine Antwort zu schicken. Sie ist zum Beispiel mitten in der Verarbeitung der Anfrage abgestürzt. Sehen Sie sich das Protokoll des Dienstes mit dem Befehl `journalctl -u dienstname -n 50 --no-pager` an, dort sollte die Ursache stehen. Wir haben das mit einer Zeile der Form `upstream prematurely closed connection while reading response header from upstream, … request: "GET /close HTTP/1.1", upstream: "http://127.0.0.1:8098/close"` nachgestellt.

</details>

<details>

<summary>upstream sent too big header while reading response header from upstream</summary>

Der Fehler 502 tritt auf, wenn die Anwendung zu lange Antwort-Header schickt, zum Beispiel riesige Cookies. Nginx liest den ersten Teil der Antwort in einen Puffer, dessen Größe standardmäßig einer Speicherseite entspricht, also 4 oder 8 KB. Passen die Header nicht hinein, gilt die Antwort als ungültig. Wir haben das an einem Header mit 9000 Zeichen Länge geprüft. Vergrößern Sie den Puffer im Block `location`.

```nginx
location / {
    proxy_pass http://127.0.0.1:8098;
    # Größerer Puffer für die Antwort-Header
    proxy_buffer_size 16k;
    proxy_buffers 8 16k;
}
```

Die Zeile `proxy_buffers 8 16k;` dürfen Sie nicht weglassen. Als wir nur `proxy_buffer_size 16k;` hinzugefügt hatten, meldete `nginx -t` den Fehler `"proxy_busy_buffers_size" must be less than the size of all "proxy_buffers" minus one buffer`, und solche Einstellungen dürfen nicht angewendet werden. Mit beiden Zeilen bestand die Prüfung, und die Seite öffnete sich mit dem Code 200.

</details>

<details>

<summary>nginx -t meldet [emerg] nach einer Änderung der Einstellungen</summary>

Das bedeutet, dass in der Konfigurationsdatei ein Fehler steckt und Nginx eine solche Konfiguration nicht anwendet. Solange Sie `systemctl reload nginx` nicht ausführen, arbeitet die Website mit den alten Einstellungen weiter, deshalb führen Sie immer `nginx -t && systemctl reload nginx` aus und nicht nur den Befehl `reload`. Der Text der Meldung zeigt, was genau nicht stimmt. Zum Beispiel weist `"proxy_busy_buffers_size" must be less than the size of all "proxy_buffers" minus one buffer` auf nicht aufeinander abgestimmte Puffergrößen im Block `location` hin.

</details>

<details>

<summary>Die Website zeigt einen Fehler, aber error.log ist leer</summary>

Höchstwahrscheinlich hat diese Website ein eigenes Fehlerprotokoll. Es wird mit der Direktive `error_log` im Block `server` festgelegt, und dann landen die Einträge in der angegebenen Datei und nicht im allgemeinen `error.log`. Wir haben das geprüft. Mit der Direktive `error_log /var/log/nginx/errors-demo.log;` im Block der Website erschien die Zeile zum Fehler 403 nur in dieser Datei. Alle Protokolle, die Nginx kennt, finden Sie mit dem folgenden Befehl.

```bash
# Alle error_log-Direktiven in allen Einstellungen anzeigen
nginx -T 2>/dev/null | grep -n error_log
```

In unserem Beispiel gab der Befehl `error_log /var/log/nginx/error.log;` aus der Hauptdatei und die Zeile mit der Adresse des Website-Protokolls aus.

</details>

<details>

<summary>curl: (7) Failed to connect to … port … Couldn't connect to server</summary>

Das ist bereits keiner der vier Fehler mehr. Nginx hat überhaupt keine Antwort geschickt, weil auf diesem Port niemand lauscht. Der Browser zeigt in diesem Fall seine eigene Seite, bei Chrome ist das `ERR_CONNECTION_REFUSED`. Diese Meldung haben wir beim Zugriff auf einen Port erhalten, den niemand belegt hatte, `curl: (7) Failed to connect to 127.0.0.1 port 8090 after 0 ms: Couldn't connect to server`. Prüfen Sie mit dem Befehl `systemctl status nginx`, dass Nginx selbst läuft, und dass die Ports 80 und 443 in der [Firewall](https://docs.f3cloud.com/de/vps/security/firewall.md) geöffnet sind.

</details>

<details>

<summary>PHP-FPM schreibt ins Protokoll Maximum execution time of 30 seconds exceeded</summary>

Das Skript lief länger, als der Parameter `max_execution_time` erlaubt, standardmäßig 30 Sekunden, und PHP hat es gestoppt. Nginx gibt dabei 500 zurück und nicht 504. Öffnen Sie `/etc/php/8.2/fpm/php.ini`, erhöhen Sie den Wert des Parameters und starten Sie den Dienst mit dem Befehl `systemctl restart php8.2-fpm` neu. Muss das Skript länger als eine Minute laufen, vergessen Sie nicht, auch `fastcgi_read_timeout` in den Nginx-Einstellungen zu erhöhen.

</details>

***

## Unsere Ressourcen

**Telegram-Kanal:** [https://t.me/f3cloud_news](https://t.me/f3cloud_news)\
**Hosting-Website:** [https://f3cloud.com](https://f3cloud.com/de)
