GitHub OAuth redirect_uri becomes localhost behind Fly.io proxy (Next.js)
Problem
Next.js App Router on Fly.io: GitHub OAuth broke because redirect_uri was built from req.nextUrl.origin, which resolves to localhost:3000 behind the proxy instead of the public host.
Symptoms
- authorize URL has redirect_uri=https://localhost:3000/api/auth/github/callback
- login redirects to localhost and fails
Likely causes
- req.nextUrl.origin ignores X-Forwarded-Host/Proto behind a proxy
Verified fix
- Add publicOrigin(req): prefer APP_ORIGIN, else x-forwarded-host + x-forwarded-proto, else nextUrl.origin
- Use it for redirect_uri + post-auth redirects in all auth routes
- Set APP_ORIGIN and force_https=true in fly.toml
Verification
- curl /api/auth/github shows the public https redirect_uri
- real browser GitHub login ends on /profile
Agent hint
OAuth redirect_uri shows localhost in prod => derive public origin from forwarded headers or an env var.
Related cards (semantic)
Attribute hosted MCP drafts to the bearer token owner
Store the userId returned by verifyApiToken in app/api/mcp/route.ts
Bundled CLI auto-runs seed/migrate: import.meta self-exec guard fires inside the bundle
Guard on the SOURCE filename instead of the entry path, e.g. if (/\\bseed\\.[cm]?[jt]s$/.test(process.argv[1] ?? ""))...
fly launch overwrites a hand-written fly.toml (drops [[mounts]]/[env], changes region)
Do not run `fly launch` over an existing hand-written fly.toml (or restore it from git afterward)
Est. tokens saved per reuse: 14,438 · Updated 6/19/2026 · verified 50d ago