Magic-Link — Troubleshooting
Emails not arriving
- Check Strapi logs for email-service errors.
- Check your email provider's send logs (Gmail sent folder, SendGrid Activity, etc.).
- If using Magic-Mail — check Magic-Mail → Email Logs.
- Verify routing — which account is being used? Is it rate-limited?
- Check spam folder — especially on first emails from a new domain.
- For production: set up SPF, DKIM, DMARC DNS records for the sending domain.
Token expired too quickly
Default expiry is 15 minutes. Increase if needed:
typescript
'magic-link': {
config: { tokenExpiry: 60 * 60 }, // 1 hour
},Or for specific users with slow email (corporate spam filters), set longer for them specifically in the admin UI.
"Token invalid" on every click
Common cause: link was scanned by an email preview service (Outlook Safe Links, McAfee GTi, etc.) which consumed the one-time token.
Fix: enable Email OTP (Premium) or browser pinning (Advanced) so pre-opens don't invalidate the flow.
Rate limited
429 Too Many Requests — Retry-After: 2400Common during dev/testing when you hit /send repeatedly. Fixes:
- Wait the
Retry-Afterseconds. - In dev, adjust config to higher limits:typescript
rateLimitPerIP: { window: 60, maxAttempts: 100 }, - For legitimate high-volume scenarios, implement Magic-Sessionmanager geo-fencing to whitelist trusted IPs.
- Unban a specific IP in admin → Magic-Link → Banned IPs.
TOTP code always rejected
Three causes:
- Clock drift — server or client clock is off by more than 30 seconds.
- Check server NTP (
timedatectl statuson Linux). - Check client device auto-time setting.
- Check server NTP (
- Wrong secret — user entered the secret manually and mistyped.
- Re-enroll: disable MFA, re-enroll with QR scan.
- Authenticator bug — rare, but some apps have drift issues.
- Try a different app (Authy → Google Authenticator).
- Use a backup code as workaround.
"User not found" on verify
Happens when autoCreateUsers: false and the email has no matching user. Either:
- Enable auto-creation:
autoCreateUsers: true. - Create users manually in admin → Users.
- Pre-register via the Users & Permissions API.
JWT validation fails
After login, your API rejects the Magic-Link JWT. Check:
- Same
JWT_SECRETacross all Strapi instances (if load-balanced). - JWT is passed in
Authorization: Bearer ...header. - Token has not expired — default Strapi JWT lifetime is 30 days.
- User is not disabled — check user record
blocked: false.
Magic-Link doesn't appear in admin sidebar
bash
rm -rf .cache dist node_modules/.cache
npm run build
npm run developCheck:
'magic-link': { enabled: true }inconfig/plugins.ts.- Logged-in admin user has permission to see the plugin (default: Super Admin can).
Enable debug mode
bash
DEBUG=magic-link:* npm run developLogs every token generation, validation attempt, rate-limit check, and email send trigger.