ARTICLE AD BOX
I have two apps running on the same server behind a Webscale proxy (Apache). A Laravel 11 app works correctly, returning a proper 302 with session cookies. My new Laravel 12 app returns 200 OK with no cookies and no Location header — just the Symfony HTML redirect fallback body.
The redirect itself is correct (the Microsoft OAuth URL is properly generated), but the response code and headers are wrong.
Controller
public function redirectToProvider() { return Socialite::driver('microsoft')->redirect(); }Route
Route::middleware('guest')->group(function () { Route::get('/login/ms', [LoginController::class, 'redirectToProvider'])->name('msauth'); });bootstrap/app.php
return Application::configure(basePath: dirname(__DIR__)) ->withRouting( web: __DIR__.'/../routes/web.php', commands: __DIR__.'/../routes/console.php', health: '/up', ) ->withMiddleware(function (Middleware $middleware): void { $middleware->trustProxies(at: '*'); }) ->withExceptions(function (Exceptions $exceptions): void { // })->create();CURL comparison
**Laravel 12 (`mynewable.newable.dev`):** ``` HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 Connection: keep-alive X-WS-Origin: available Server: Apache ``` No cookies. No `Location` header. No `Cache-Control`.
**Laravel 11 (`mynewable.co.uk`) — same server, same proxy:** ``` HTTP/1.1 302 Found Content-Type: text/html; charset=utf-8 Cache-Control: no-cache, private Set-Cookie: XSRF-TOKEN=... Set-Cookie: mynewable_session=... Location: https://login.microsoftonline.com/... Strict-Transport-Security: ... X-XSS-Protection: ...
What I've ruled out
Not a caching issue — happens on fresh requests with no prior cache
Not a routing issue — php artisan route:list shows the correct controller method
Not a code issue — works perfectly in local Laragon environment
Not a proxy issue — the L11 app on the same server behind the same proxy works fine
TrustProxies — already set to * in bootstrap/app.php
bootstrap/app.php — completely default, nothing custom added
All caches cleared — php artisan optimize:clear run before every test
The missing response headers on the L12 app (no Cache-Control, no cookies, no security headers) suggest Laravel isn't completing the response pipeline properly, but I can't find why.
Has anyone seen this behaviour with Laravel 12 behind a reverse proxy, and is there something in the new middleware/kernel structure that needs explicit configuration that Laravel 11 handled automatically?
