Ghost admin interface unusable – 2FA + Cookie + Login Loop Nightmare (Ghost v5.130.3)

Hello everyone,

I need to vent and ask for real help because I’m losing my mind.

The issue: I cannot log in to the Ghost admin interface.

Summary:

  • Ghost version: 5.130.3

  • Self-hosted on Ubuntu 24.04 LTS

  • Reverse proxy: Nginx

  • Database: MySQL

  • Mail: SMTP (Gmail, working)

  • Browser: Standard Chrome/Firefox

  • Config is set to: "trustProxy": true, and HTTPS works.


:fire: What’s going wrong?

  1. 2FA Login process is broken

    • Ghost keeps saying “A 6-digit sign-in verification code has been sent to your email…”

    • The code is invalid anyway when I try it. Every time.

  2. Cookie/session not persisted

    • Even after disabling 2FA logic in session/middleware.js, the login form reloads

    • I enter correct email + password, click login → page refreshes, no error → form shows up again

    • Ghost sets no persistent session cookie

    • Authorization failed – Unable to determine the authenticated user or integration keeps showing up in logs.

  3. Tried to debug for days

    • SMTP manually tested: works fine via nodemailer + Ghost’s internal sendMail

    • Set logging.level = "trace"

    • Deleted sessions/tokens in DB

    • Tried skipVerification, disabled 2FA logic in code

    • Logs only say the auth fails silently, no clear error

    • Even added "twoFactorAuthentication": false in config.production.json, nothing changes

    • No obvious error on login page

    • Cookies look either not being set, or discarded immediately

My nginx config has all the required headers:

proxy_set_header X-Forwarded-Proto $scheme;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header Host $host;

proxy_pass http://127.0.0.1:2368;

proxy_http_version 1.1;

proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host;

proxy_cookie_path / "/; Secure; HttpOnly; SameSite=None";

trustProxy is set to true, yet it’s as if Ghost refuses to trust cookies or allow sessions to persist.

This is Ghost. It should be simple. Login → dashboard. Yet I’m stuck for 3 full days in a broken auth loop I’ve never seen in any other framework.

If anyone has an idea:

  • How to disable ALL auth/session verification temporarily?

  • How to force Ghost to trust its own cookie?

  • How to bypass 2FA for an existing user?

I will appreciate any insight. But please: I’ve been through all official docs and posts. Nothing fixes this loop.

Thanks.

Given that you said you’ve tried all docs and posts, have you tried setting staffDeviceVerification, as documented here?

I am asking because neither twoFactorAuthentication, trustProxy, or skipVerification are valid config keys, so wondering where you got these from.

Generally, no code changes should be necessary to make this work, of course.

I have seen loops like this before, and it always had to do with caching. Any chance there’s some form of caching going on?

1 Like

Is this a new install? If not, what changed when it broke?

I don’t have an immediate answer for you, but a few thoughts, with apologies if you’ve already tried them:

Are you very sure your browser or some security plugin isn’t wiping cookies?

The config file setting to disable 2FA is not the one you listed. It’s (ah, Jannis beat me to it!)

The fact that you have keys that don’t seem to exist makes me wonder if AI is “helping” and you’re deep in a hallucination. If your setup allows (and this is a new install without data to preserve), at this point it might make the most sense to do a fresh install, including letting ghost cli handle nginx config.

1 Like