Login Loop - CSRF Check Failed on ALL Fresh Login Attempts (Internal AND External) with Cloudflare Tunnel

I’m trying to set up external access to my Nextcloud instance via Cloudflare Tunnel, but I’ve run into a login loop issue that affects both external AND internal access. When I try to login in incognito mode (or any fresh browser session), I get stuck in an infinite redirect loop. The only way I can access Nextcloud is through my regular browser that still has old session cookies.

After extensive troubleshooting, I’ve narrowed it down to a CSRF validation failure - the logout button shows ā€œAccess forbidden - CSRF check failedā€. This happens on both http://192.168.0.x:8080 (internal LAN) and my Domain (external via Cloudflare Tunnel).

I’ve verified that headers are forwarded correctly, HTTPS is detected properly, trusted proxies are configured with all Cloudflare IP ranges, sessions are being created, and there are no authentication errors in the logs. Everything appears to be configured correctly, yet CSRF validation keeps failing.

Has anyone encountered this specific CSRF issue with Nextcloud? Any ideas what could be causing this? Here’s the full breakdown:

-–

Setup

- Nextcloud: v32.0.6.1 running in Docker on Ugreen NAS

- Access Method: Cloudflare Tunnel (cloudflared)

- Domain: Not going to post it here but i have a domain i am using (using Cloudflare)

- Internal Access: http://192.168.0.x:8080 (login loop in incognito)

- External Access: My Domain (login loop)

The Problem

I get stuck in an infinite login loop on BOTH internal and external access:

1. Enter credentials

2. Click login

3. POST /login returns HTTP 200 (not 302 redirect)

4. Browser shows login page again

5. Repeat

CRITICAL DISCOVERY:

- Logout shows ā€œAccess forbidden - CSRF check failedā€

- Login loop happens on BOTH http://192.168.0.x:8080 AND https://example.com

- Only works in my regular browser with old session cookies

- Fresh login attempts (incognito) fail everywhere

What I’ve Verified:

Headers Are Being Forwarded Correctly

Created a test script that shows:


X-Forwarded-Proto: https
X-Forwarded-For: \[my IPv6\]
Cf-Visitor: {"scheme":"https"}
HTTPS: on (Apache is reading the header)
REMOTE_ADDR: \[my IPv6 address\]

Nextcloud Configuration


'trusted_domains' => \[
'192.168.0.x:8080',
'192.168.0.x',
'My Domain'
\],

'trusted_proxies' => \[
'127.0.0.1',
'::1',
'172.21.0.1',
'192.168.0.x',

// All Cloudflare IPv4 ranges

'173.245.48.0/20',
'103.21.244.0/22',

// ... (all 10 ranges)

// All Cloudflare IPv6 ranges
'2400:cb00::/32',
'2606:4700::/32',
// ... (all 7 ranges)
\],

'forwarded_for_headers' => \[
'HTTP_X_FORWARDED_FOR',
'HTTP_CF_CONNECTING_IP',
'HTTP_X_FORWARDED_PROTO',
'HTTP_X_FORWARDED_HOST'
\],

'overwrite.cli.url' => my Domain

Apache Configuration

- `remoteip` module enabled (then disabled during troubleshooting)

- `SetEnvIf X-Forwarded-Proto ā€œhttpsā€ HTTPS=on` configured

- PHP correctly sees `$_SERVER[ā€˜HTTPS’] = ā€˜on’`

Sessions

- PHP session path configured: `/var/www/html/data/sessions`

- Session files are being created

- Permissions are correct (www-data:www-data, 700)

Cloudflare Tunnel

- Tunnel is running and connected

- Route: mydomain→ http://192.168.0.x:8080

- No Cloudflare Access application interfering

What We’ve Tried

1. Added all Cloudflare IP ranges (IPv4 and IPv6) to trusted_proxies

2. Configured forwarded_for_headers

3. Set overwritehost and overwriteprotocol (then removed them)

4. Tried with and without overwritecondaddr

5. Enabled Apache remoteip module (then disabled it)

6. Configured PHP session storage

7. Removed Cloudflare Access

8. Verified HTTPS detection is working

9. Checked logs (no authentication errors)

10. Tested in multiple browsers and incognito mode

11. Ran `php occ maintenance:repair`

12. Ran `php occ maintenance:update:htaccess`

13. Reset user password

14. Cleared all caches

Observations

- **CSRF check failed - Logout shows ā€œAccess forbidden - CSRF check failedā€

- No POST requests appear in logs - only GET /login requests

- Cookies are being set- I can see session cookies in browser

- No errors in Nextcloud logs - just deprecation warnings

- Login loop affects ALL fresh attempts - both internal IP and external domain

- Old sessions still work - regular browser with existing cookies works fine

The Mystery

Everything appears to be configured correctly, but CSRF validation is failing:

- Headers are forwarded correctly

- HTTPS is detected correctly

- Trusted proxies configured correctly

- Sessions are created correctly

- Trusted domains include both IP and domain

- But CSRF check fails

This affects ALL fresh login attempts (not just external). The login form submission appears to be rejected due to CSRF token validation failure.

Question

Has anyone successfully set up Nextcloud with Cloudflare Tunnel and encountered this CSRF issue? What am I missing?

-–

Environment Details:

- Nextcloud: 32.0.6.1 (Docker official image)

- Database: MariaDB 10.6

- PHP: 8.3.30

- Apache: 2.4.66

- Cloudflare Tunnel: Latest version

- NAS: Ugreen DXP4800PRO

Please make sure to use occ config:list system to view your merged configuration (particularly since most of the Docker images used multiple config files).

Steps are described in the support template.

Also make sure Cloudflare’s Rocket Loader feature is off.

Solved.
The root cause was a session storage issue. The Docker image was configured to use Redis for PHP sessions, but the connection was failing. When i switched to file-based sessions, the sessions directory didn’t exist, so PHP couldn’t write session files. Creating the directory with proper permissions solved it.

This topic was automatically closed 8 days after the last reply. New replies are no longer allowed.