3 min read

Ghost Admin Login Gets Stuck on "Signing in": The staffDeviceVerification Problem

I recently encountered a frustrating Ghost issue that had me completely stumped. I could not log into my Admin account. If you're experiencing similar symptoms after a server migration or a fresh Ghost installation, the culprit might be Ghost's staffDeviceVerification security feature.
Ghost Admin Login Gets Stuck on "Signing in": The staffDeviceVerification Problem
Photo by FlyD / Unsplash

I recently encountered a frustrating Ghost issue after I migrated from Digital Ocean to Hetzner that had me completely stumped. When trying to log into my Ghost admin panel, I'd enter my credentials and click "Sign in," but then get stuck on the loading screen showing "Signing in..." The login process would hang for minutes before eventually failing with a gateway timeout error.

If you're experiencing similar symptoms after a server migration or a fresh Ghost installation, the culprit might be Ghost's staffDeviceVerification security feature.

The Symptoms

Here's what the user experience looked like:

  1. Enter email and password on the login page
  2. Click "Sign in"
  3. Page shows "Signing in..." loading state
  4. Wait... and wait... and wait...
  5. Eventually get a gateway timeout, or the page just stays stuck loading

In the Ghost logs, I could see the session endpoint taking an extremely long time:

INFO "POST /ghost/api/admin/session" 200 60046ms

That's over 60 seconds for a login request that should complete in milliseconds. After this lengthy delay, subsequent API calls would fail:

ERROR "GET /ghost/api/admin/users/me/?include=roles" 403 6ms

NAME: NoPermissionError
MESSAGE: Authorization failed
"Unable to determine the authenticated user or integration. Check that cookies are being passed through if using session authentication."

What is staffDeviceVerification?

Ghost includes a security feature called staffDeviceVerification that adds device-based authentication for admin users. When enabled, Ghost requires email verification for each new device that attempts to log into the admin panel.

Here's how it works:

  1. You log in from a new device
  2. Ghost sends a verification email
  3. You click the verification link to mark the device as trusted
  4. Future logins from that device don't require re-verification

Why It Breaks After Server Changes

The problem occurs because Ghost uses various factors to create a "device fingerprint" - things like IP addresses, server environment variables, and session configurations. When you migrate to a new server or significantly change your setup, these fingerprints change.

Ghost then considers your device "untrusted" and expects you to verify it via email. But if your email isn't configured properly, the login process gets stuck because:

  1. Ghost accepts your password credentials
  2. Ghost tries to send a device verification email
  3. Email sending fails or times out (due to misconfigured email settings)
  4. The login request hangs waiting for the email process to complete
  5. Eventually the request times out, leaving you stuck on "Signing in..."

This creates the frustrating experience where you know your password is correct, but the login process just hangs indefinitely.

The Solution

The fix is surprisingly simple: temporarily disable device verification in your Ghost configuration.

Edit your config.production.json file and add or modify the security section:

{
  "url": "https://yourdomain.com",
  "database": {
    // your database config
  },
  "security": {
    "staffDeviceVerification": false
  }
}

Then restart Ghost:

ghost restart

When Should You Use Device Verification?

Device verification is genuinely useful in certain scenarios:

Enable it when:

  • You have multiple admin users accessing Ghost
  • You frequently log in from different locations/devices
  • You have a high-security blog with sensitive content
  • Your email system is properly configured and reliable

Disable it when:

  • You're the only admin user
  • You've recently migrated servers
  • You're having email delivery issues
  • You're still setting up your Ghost installation

Alternative: Fix Your Email Configuration

If you want to keep device verification enabled, make sure your Ghost email configuration is working properly. Test it with a simple command:

ghost config mail.transport SMTP
ghost config mail.options.host your-smtp-server.com
ghost config mail.options.port 587
ghost config mail.from your-email@domain.com

You can test email functionality by requesting a password reset - if that email arrives, device verification should work too.

The Broader Lesson

This issue highlights a common problem with modern web applications: security features that work great in stable environments can become roadblocks during migrations or configuration changes.

Ghost's device verification is well-intentioned and genuinely useful for multi-user blogs, but it can create authentication loops that are difficult to diagnose. The error messages don't clearly indicate that device verification is the problem - they just show generic "Authorization failed" messages.

Prevention for Future Migrations

If you're planning a Ghost migration, consider disabling staffDeviceVerification before starting the migration process. You can always re-enable it once everything is stable and your email system is confirmed working.

This small configuration change can save you hours of debugging session management and proxy configurations that may not actually be the root cause of your authentication issues.

Remember: sometimes the solution to complex technical problems is simpler than you think. When Ghost login works but the admin panel doesn't, check your security settings before diving deep into server configurations.