Skip to content

Magic link emails not enqueued in 6.27.0 (201 response, outbox empty, 6.26.0 works) #468

@TheBig-O

Description

@TheBig-O

After upgrading from Ghost 6.26.0 to 6.27.0, admin/staff login magic link emails are no longer being sent, even though the send-magic-link API returns 201 and there are no mail-related errors in the logs. The process-outbox job runs but reports no pending outbox entries to process. If I roll back to 6.26.0, magic links work immediately with the same database and SMTP config.

This looks like a regression in the members/magic-link → outbox pipeline between 6.26.0 and 6.27.0, rather than an SMTP or config issue.


Environment

  • Ghost: 6.26.0 (working), 6.27.0 (failing)
  • Install: self-hosted, Docker
  • Ghost image: ghost:6.26.0-alpine (working), ghost:6-alpine (6.27.0, failing)
  • Database: MySQL 8 (in Docker)
  • Mail: Gmail SMTP (app password), verified working on 6.26.0
  • Reverse proxy: Traefik
  • URL: generic public URL (self-hosted; anonymized here)

Relevant configuration

docker-compose excerpt (Ghost service):

services:
  ghost:
    image: ghost:6-alpine         # 6.27.0
    container_name: ghost
    restart: unless-stopped
    networks:
      - proxy
      - ghost
    ports:
      - 8088:2368
    environment:
      database__client: mysql
      database__connection__host: <db-host>
      database__connection__port: <db-port>
      database__connection__user: ghost
      database__connection__password: ********
      database__connection__database: ghost
      url: https://example.com/blog/
    volumes:
      - /path/to/config.production.json:/var/lib/ghost/config.production.json:ro
      - /path/to/content:/var/lib/ghost/content

config.production.json mail section (used by both 6.26.0 and 6.27.0):

"mail": {
  "from": "Blog Admin <no-reply@example.com>",
  "transport": "SMTP",
  "options": {
    "service": "Gmail",
    "host": "smtp.gmail.com",
    "port": 587,
    "secure": false,
    "auth": {
      "user": "no-reply@example.com",
      "pass": "GMAIL_APP_PASSWORD"
    }
  }
}

Notes:

  • This config sends magic link emails successfully in 6.26.0.
  • The file is mounted into /var/lib/ghost/config.production.json and verified inside the container.
  • The Missing mail.from config warning was present initially but resolved; it does not appear in 6.27.0 logs anymore.

What works (6.26.0)

With image: ghost:6.26.0-alpine:

  1. Start Ghost.

  2. Visit /blog/admin/, enter a staff user email to log in.

  3. Logs show:

    INFO "POST /blog/members/api/send-magic-link/" 201 ...
    ...
    # then the outbox job runs and sends the email
    INFO "POST /blog/members/api/verify-otc/" 200 ...
    INFO "GET /blog/members/?token=...&action=signin..." 302 ...
    
  4. Magic link email arrives in the inbox.

  5. The Gmail account used for SMTP also shows the outgoing email in its “Sent” folder.

So in 6.26.0 the magic link flow and SMTP are both working correctly.


What fails (6.27.0)

Switch only the Ghost image to ghost:6-alpine (6.27.0), keeping the same DB and config:

  1. Start Ghost; logs:

    INFO Ghost is running in production...
    INFO Ghost database ready...
    # no "Missing mail.from" warning
    
  2. Visit /blog/admin/, enter the same staff email to log in.

  3. Logs show:

    INFO "GET /blog/members/api/integrity-token/" 200 ...
    INFO [Inbox links] Found no inbox links
    INFO "POST /blog/members/api/send-magic-link/" 201 ...
    ...
    INFO Worker for job "process-outbox" online
    INFO Worker for job process-outbox sent a message: done
    INFO [OUTBOX] No pending outbox entries to process
    
  4. There are no EmailError, Failed to send email, EAUTH, or other mail-related errors.

  5. No magic link email is received.

  6. The Gmail SMTP account’s “Sent” folder shows no new magic link emails for these attempts.

From the logs it appears that:

  • send-magic-link returns 201.
  • process-outbox finds no queued jobs.
  • SMTP is never hit; Ghost does not log any error.

This suggests the magic link flow is not enqueuing an outbox job in 6.27.0, despite returning a success status.


What I’ve already tried

  • Verified mail.from and full SMTP settings in config.production.json.
  • Fixed the Missing mail.from config warning; it no longer appears in 6.27.0.
  • Confirmed the config file contents inside the 6.27.0 container.
  • Confirmed Gmail SMTP and magic links work under Ghost 6.26.0 with the same DB and config.
  • Migrated to MySQL 8 with a clean schema and imported content; all other Ghost features appear to work.
  • Tested both port 465 (secure: true) and 587 (secure: false) with the same Gmail app password.
  • Checked logs around send-magic-link, outbox, and email; 6.27.0 logs contain no mail-related errors at all.

Expected behavior

On 6.27.0:

  • POST /members/api/send-magic-link should:
    • Create an outbox entry.
    • Be picked up by process-outbox.
    • Send the magic link email via the configured SMTP transport.

Actual behavior

On 6.27.0:

  • POST /members/api/send-magic-link returns 201.
  • process-outbox immediately reports: [OUTBOX] No pending outbox entries to process.
  • No magic link email is sent.
  • No SMTP traffic appears in the Gmail account’s “Sent” folder.
  • No errors or warnings are logged by Ghost for this flow.

Reverting the Ghost image back to 6.26.0 with the same DB and config immediately restores working magic link sign-in.


Question

Is there a known change in 6.27.0 around the members magic-link / outbox pipeline that could cause send-magic-link to return 201 but skip enqueuing an outbox job (e.g., based on member state, settings, or imported data)?

If not, this appears to be a regression between 6.26.0 and 6.27.0 in the magic-link sign-in flow on self-hosted Docker + MySQL, and I’d appreciate guidance on how to debug or confirm this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions