Fix Laravel Session Not Working — Login Immediately Logs Out (2025)
🔐 Fix “Session Not Working — User logs in then immediately logs out” (Laravel, 2025)
Error (symptom):
User logs in but is immediately logged out / session not persisting
This problem usually comes from cookie, session driver, domain, or server configuration issues. Let’s fix it step-by-step.
🔍 Why this happens (common causes)
Wrong SESSION_DOMAIN — cookie domain doesn’t match your app domain (subdomain vs root domain).
Session driver misconfigured (file vs database vs redis) or driver failing.
Secure cookie / HTTPS mismatch — cookie set as secure but site served over HTTP (or vice-versa).
Storage permission issues (when using file driver): Laravel can’t write session files.
Multiple servers/load balancer without sticky sessions or central session store.
Browser blocking cookies (SameSite policy or third-party cookie blocking).
APP_URL mismatch (scheme / domain differs from what cookie expects).
Expired sessions or very short SESSION_LIFETIME.
🛠 Step-by-step fixes (do these in order)
1) .env — set sensible session settings
Example .env recommended values:
APP_URL=https://yourdomain.com
SESSION_DRIVER=file # or database, redis, etc.
SESSION_DOMAIN=.yourdomain.com # note leading dot for subdomains (or null for localhost)
SESSION_SECURE_COOKIE=true # true if using HTTPS, false for HTTP (use HTTPS in production)
SESSION_LIFETIME=120 # minutes
SESSION_SAME_SITE=lax # 'lax' is default; use 'none' only if cross-site cookies required (with secure=true)
Notes:
For local development (localhost) use SESSION_DOMAIN=null or leave empty.
For subdomain support (eg. app.yourdomain.com + www.yourdomain.com), set SESSION_DOMAIN=.yourdomain.com (leading dot).
If you use SESSION_SECURE_COOKIE=true, ensure APP_URL uses https:// and your site is served via HTTPS.
2) Clear Laravel caches
After updating .env always clear config/cache so Laravel picks up changes:
php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan view:clear
(Optionally restart PHP-FPM / workers after this.)
3) Check session storage & permissions (when using file driver)
If using file driver (default), sessions are stored in storage/framework/sessions. Ensure Laravel can write there:
sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cache
(Replace www-data with your web server user.)
4) If using database driver — create session table
If SESSION_DRIVER=database, create the table:
php artisan session:table
php artisan migrate
Confirm sessions are being written to the table.
5) If using redis/memcached — check connection
If SESSION_DRIVER=redis or memcached, verify connections in config/database.php and config/cache.php. Test that Redis is reachable and credentials are correct.
6) Inspect browser cookies (quick debug)
Open DevTools → Application (Chrome) → Cookies:
Look for cookie name (default laravel_session).
Check Domain, Path, Secure, SameSite, Expires.
If cookie is missing, the app didn’t set it (server issue). If cookie is present but login still fails, the server likely cannot read/validate session.
7) APP_URL, reverse proxies & HTTPS
Ensure APP_URL matches the public URL (including scheme).
If behind a proxy/load balancer, configure trusted proxies (e.g., fideloper/proxy or built-in handling) so Laravel knows requests are HTTPS. Otherwise cookies may be marked insecure or redirect incorrectly.
8) Multiple servers / load balancer
In a multi-server setup, use a central session store (Redis or database) or enable sticky sessions at the load balancer. File sessions will not work if requests go to different servers.
🔎 Quick troubleshooting checklist
.env values (SESSION_DOMAIN, SESSION_SECURE_COOKIE, APP_URL) correct
php artisan config:clear run after .env changes
Cookie appears in browser and domain/path match site
storage/framework/sessions writable (for file driver)
If database driver — sessions table exists & receives rows
If using redis/memcached — connection is alive
No conflicting middleware or custom guard expiring sessions
If deployed behind proxy — trusted proxies configured
🎯 Pro tips (best practices)
Use SESSION_DRIVER=redis (or database) in production for reliability across multiple servers.
Always use HTTPS in production and set SESSION_SECURE_COOKIE=true.
For subdomains, use SESSION_DOMAIN=.yourdomain.com and SESSION_SAME_SITE=None (only if needed) with secure cookie.
Use php artisan serve only for local testing — real webserver behavior may differ.
Monitor session writes (logs or DB) to confirm sessions are created.