Weiße Seite hinter dem Reverse-Proxy: der Präfix, den niemand mitnimmt
Lokal läuft die App, hinter dem Reverse-Proxy bleibt die Seite weiß — ohne Fehlermeldung. Warum ein führender Schrägstrich den Präfix verliert, in welchen drei Formen der Fehler auftritt und wie man ihn mit einem eigenen Prüfstand messbar macht.
Eine kleine Web-App, lokal tadellos: Oberfläche da, Daten da, Knöpfe tun, was sie sollen. Dieselbe App hinter dem Reverse-Proxy der Plattform ausgeliefert: weiße Seite, keine Fehlermeldung, im Container-Log kein einziger eingehender Treffer. Der Unterschied ist kein Bug im Code, sondern ein Zeichen zu viel am Anfang eines Pfades.
Was der Proxy mit dem Pfad macht
Die App läuft nicht unter einer eigenen Domain, sondern unter einem Unterpfad: etwas in der Art von /apps/proxy/meine-app/8080/. Der Proxy schneidet diesen Präfix ab und reicht den Rest an den Container weiter. Die App bekommt also / zu sehen und hat keinerlei Kenntnis davon, unter welcher Adresse sie beim Besucher erscheint.
Solange der Browser nur die Startseite holt, merkt niemand etwas. Das Problem beginnt beim zweiten Request. Steht im HTML src="/static/app.js" oder im JavaScript fetch("/api/daten"), löst der führende Schrägstrich gegen die Domain-Wurzel auf, nicht gegen den Präfix. Der Browser fragt also die Plattform nach /api/daten. Die antwortet brav — meistens mit ihrer eigenen HTML-Hülle und einem fröhlichen 200. Der Request erreicht den Container nie, das JavaScript bekommt HTML statt JSON, und die Seite bleibt leer. Ein 200 ist hier die unangenehmste Antwort von allen: ein 404 hätte man sofort gesehen.
Die drei Formen, in denen der Fehler auftritt
Der Fix pro Fundstelle ist trivial, das Finden ist die Arbeit. In der Praxis tritt die Klasse in drei Gestalten auf, und die zweite und dritte überlebt man gern, weil man nach der ersten aufhört zu suchen.
- Harte absolute Pfade in HTML, CSS und JavaScript:
fetch("/api/..."),src="/static/...",url(/fonts/...). Der Klassiker, und der einzige, der sofort weh tut. - Zusammengebaute Adressen, typischerweise über
location.origin. Das Feld enthält Schema und Host — und genau nicht den Pfad. Werlocation.origin + "/api/daten"schreibt, hat denselben Fehler nur eleganter formuliert. Richtig ist, den aktuellenpathnamemitzunehmen oder konsequent relativ zu bleiben. - Framework-Defaults, die man nicht selbst getippt hat: Weiterleitungen mit absolutem
Location-Header (nach dem Login landet der Besucher auf dem Plattform-Dashboard statt in der App), Asset-Präfixe, und als leiseste Variante das Web-App-Manifest samt Service-Worker-Scope. Letztere machen gar nichts kaputt, bis jemand die App installieren will. Dann ist der Scope falsch, und niemand verbindet das mehr mit einem Deployment von vor drei Monaten.
Der Prüfstand: ein Proxy, der genauso schneidet
Die Versuchung bei "sieht noch gleich aus" ist, einfach noch einmal neu zu bauen. Das kostet Minuten und beweist nichts. Besser ist ein Prüfstand, der die Umgebung nachstellt: ein kleiner lokaler Reverse-Proxy, der einen beliebigen Präfix abschneidet und an den Container weiterreicht. Das sind wenige Zeilen Konfiguration oder ein kurzes Skript, und ab dann ist der Fehler reproduzierbar statt anekdotisch.
Darauf laufen vier Abfragen, die den Zustand vollständig beschreiben: die Startseite, ein Asset, ein API-Aufruf und eine Weiterleitung. Bei der Weiterleitung interessiert nicht der Inhalt, sondern der Location-Header. Gemessen wird immer, was der Container ausliefert — nicht, was im Quellbaum steht. Diese Unterscheidung ist wichtiger, als sie klingt: ein Fix kann committet, gepusht und trotzdem nie ausgerollt sein.
Ein verwandter Stolperstein wohnt direkt daneben. Liefert das Framework statische Dateien nur mit ETag und ohne Cache-Control aus, schätzt der Browser die Haltbarkeit selbst — und zeigt tagelang altes JavaScript, obwohl der Container längst das neue ausliefert. Wer dann den Rebuild wiederholt, behandelt das falsche System.
Nicht die Fundstelle reparieren, sondern das Muster
Nach dem ersten Treffer lohnt ein Schritt, der sich jedes Mal auszahlt: die Signatur des Fehlers aufschreiben und damit den ganzen Baum durchsuchen. Für diese Klasse ist die Signatur das Anführungszeichen vor dem Schrägstrich — "/api, '/static, src="/. Ein Grep darüber liefert in aller Regel Geschwister, die noch nicht gemeldet wurden, weil ihr Pfad noch keiner angeklickt hat.
Eine Besonderheit haben Werte, die zur Bauzeit gebraucht werden, etwa ein Asset-Präfix. Wer die passende Variable nur zur Laufzeit in die Container-Umgebung legt, hat sie still nicht gesetzt: der Build hat sie nie gesehen, das Ergebnis ist unverändert, und es gibt keine Fehlermeldung darüber. Diese Sorte Nicht-Wirkung ist der Grund, warum man am Ende messen muss und nicht lesen darf.
Fazit
Der eigentliche Fix dieser Fehlerklasse ist ein gelöschter Schrägstrich. Die Arbeit liegt davor und danach: einen Prüfstand bauen, der den Präfix tatsächlich abschneidet, am ausgelieferten Ergebnis messen statt am Quellbaum, und nach dem ersten Treffer das Muster im ganzen Projekt suchen. Wer nur die gemeldete Stelle anfasst, repariert das Symptom und bekommt denselben Fehler in vier Wochen mit einer anderen Datei im Betreff.
- #Reverse-Proxy
- #Deployment
- #Debugging
- #Pfade
- #Caching
- #Web-Apps
Weiterlesen
Proxy gesetzt, trotzdem direkt: warum WebSockets an HTTPS_PROXY vorbeilaufen
1. November 2026 · Engineering, KI-Agenten, DevOps · 4 Min. Lesezeit
Nullbefund ist kein Befund: wann eine leere Suche etwas beweist
29. Oktober 2026 · Engineering, Automatisierung, KI-Agenten · 4 Min. Lesezeit
Gepusht ist nicht ausgeliefert: wie ich belege, welcher Stand wirklich im Container läuft
28. Oktober 2026 · Engineering, DevOps, Automatisierung · 4 Min. Lesezeit