Why a proxy changes what your app believes
In many hosting set-ups the visitor's HTTPS connection ends at a proxy, load balancer or content network, and the proxy talks to your app over plain HTTP on a private network. From the app's point of view every request then looks like HTTP from a single internal address. The proxy normally adds headers that describe the original request: the forwarded protocol, the forwarded host and the client address. Whether the app uses them depends on a setting that is usually off by default. In Express the trust proxy setting defaults to false, meaning the app assumes it faces the client directly, and when it is enabled the forwarded protocol is what the app reports as the request protocol.
That matters for login. The session library only sets a Secure cookie on a connection it considers secure. express-session documents that if the Secure attribute is requested and the site is accessed over HTTP, the cookie will not be set, and that behind a proxy the trust proxy setting must be enabled. The cookie is silently never issued, so every request looks signed out.
- Symptom: login works on localhost, fails on the live HTTPS address.
- Symptom: the app generates http:// callback or redirect addresses on an HTTPS site.
- Symptom: client addresses in logs are always the proxy's address.
The same mistake in other frameworks
The mechanism is general even though the setting name differs. Auth.js version 5 infers the host from request headers; its deployment documentation says that behind a reverse proxy AUTH_TRUST_HOST should be set to true so that it trusts the forwarded host header, and that this is inferred automatically on Vercel and Cloudflare Pages. A wrong host produces a wrong callback address, which then fails at the provider as a redirect mismatch. Other frameworks have an equivalent setting for trusted proxies; check yours rather than assuming it is on.
- Find the framework's trusted-proxy or forwarded-header setting.
- Check whether it is automatic on your host or needs to be set.
- Check it after every change of host, proxy or content network.
Trusting the proxy safely
Do not simply turn trust on everywhere. Express warns that when trust is enabled in its simplest form the last trusted proxy must remove or overwrite the forwarded headers, otherwise a client can supply any value, and that the setting must match how the proxy actually operates, for example by naming the number of hops or the proxy addresses. A visitor who can reach the app directly and send a forged forwarded-protocol header could otherwise make it believe the request is secure.
- Trust only the proxies you run, by address or hop count.
- Make sure the proxy overwrites, not appends to, the forwarded headers.
- Do not expose the app on a public address that bypasses the proxy.
A safe first investigation
Use a test account. In the browser developer tools, check whether the login response sets a cookie. If it does not, ask the app to report, in a test environment, what protocol and host it believes the request used, and compare that with the address in the browser. Ask your hosting contact whether the proxy forwards the protocol and host headers and whether it overwrites any copy sent by the client. Do not send cookie values, certificates or configuration containing secrets.
- Cookie not set at all: look at trust and Secure first.
- Cookie set and not returned: see the cookie attributes guide.
- Callback address wrong: see the redirect address guide.
What fixes it and how the paid job is accepted
The repair is usually an app-side setting that trusts your own proxy for the forwarded protocol and host, plus written steps for any proxy setting only your hosting contact can change. It is not a request to switch Secure off. Our login-session repair (posted test price from £295, untested, paid only after sign-off) is accepted when a test user stays signed in across ten page loads in each agreed environment behind the same proxy path (and across a browser restart where a lasting session is agreed in writing), and the cookie shows the agreed attributes. Your team applies host changes and deploys. Send the two addresses and your hosting set-up in your first enquiry, not credentials or cookie values.
Sources and limits
- Express: Behind proxies Checked 2026-10-11.
- The trust proxy setting defaults to false; when enabled, X-Forwarded-Proto is reflected by req.protocol; the last trusted proxy must remove or overwrite the forwarded headers or a client may supply any value; the setting must match how the proxy actually operates (Express 5.x documentation).
- express-session Checked 2026-10-11.
- If cookie.secure is set and the site is accessed over HTTP the cookie will not be set; behind a proxy trust proxy must be set; the default cookie does not set the Secure attribute.
- Auth.js: Deployment Checked 2026-10-11.
- Behind a reverse proxy AUTH_TRUST_HOST should be true so Auth.js trusts the X-Forwarded-Host header; it is inferred automatically on Vercel and Cloudflare Pages (v5 documentation).
- MDN: Set-Cookie header Checked 2026-10-11.
- Insecure (http:) sites cannot set cookies with the Secure attribute.