My portfolio runs as a static export in an nginx container, published through a Cloudflare Tunnel. Cloudflare terminates TLS, handling encryption with the visitor, then forwards to my server over plain HTTP.
nginx took that personally.
- Symptom
- A client-side POST to the contact form backend failed, but only on some routes. Pages loaded fine over HTTPS. Nothing in the console pointed at the server.
- Cause
- nginx built absolute
Location:headers using its own scheme, which was HTTP, silently downgrading every trailing-slash redirect. - Fix
absolute_redirect off;
The chain
nginx's automatic directory redirects, /projects to /projects/, build an
absolute Location: header using nginx's own scheme. Since the tunnel talks to
nginx over HTTP, that scheme is HTTP, and so every trailing-slash redirect walked
the visitor downhill:
- Visitor arrives on
https://ariefrse.my/projects - Page hits a trailing-slash redirect
- Visitor lands on
http://ariefrse.my/projects/
The browser follows without complaint. The page still renders. Nothing looks broken, which is precisely why it survived.
One line fixes it:
# nginx.conf
absolute_redirect off;
Relative redirects, Location: /projects/, let the browser keep whatever scheme
it arrived on.
The bug behind the bug
Here is the part I find harder to forgive than the nginx default.
The contact form had been "working" the entire time, because it faked success
with a setTimeout and never sent anything anywhere. Wiring it up for real is
what exposed the downgrade.
A fake implementation does not merely fail to deliver. It masks the infrastructure bugs that a real one would have surfaced months earlier. The placeholder was not neutral. It was actively holding the door shut on a finding.