nextauthjs/next-auth · error · Error

Forward Email error: ${JSON.stringify(await res.json())}

Error message

Forward Email error: ${JSON.stringify(await res.json())}

What it means

The Forward Email provider throws this when the Forward Email HTTP API responds with a non-OK status during sendVerificationRequest. The provider intentionally includes the full JSON error body returned by the API so the developer can see exactly why the send failed (auth, domain, rate limit, etc.). It aborts the sign-in email flow, so the user never receives the verification link.

Source

Thrown at packages/core/src/providers/forwardemail.ts:31

      const { identifier: to, provider, url, theme } = params
      const { host } = new URL(url)
      const res = await fetch("https://api.forwardemail.net/v1/emails", {
        method: "POST",
        headers: {
          Authorization: `Basic ${btoa(provider.apiKey + ":")}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          from: provider.from,
          to,
          subject: `Sign in to ${host}`,
          html: html({ url, host, theme }),
          text: text({ url, host }),
        }),
      })

      if (!res.ok)
        throw new Error(
          "Forward Email error: " + JSON.stringify(await res.json())
        )
    },
    options: config,
  }
}

View on GitHub (pinned to a1a16a5a77)

Solutions

  1. Check res/API error JSON in the message for auth errors; verify FORWARD_EMAIL_API_KEY is set and valid
  2. Verify the sending domain in your Forward Email account matches provider.from
  3. Retry after backoff if the body indicates rate limiting (429)
  4. Add logging around sendVerificationRequest to capture the full response body

Example fix

// before
default: {
  type: "email",
  // apiKey not configured -> API returns 401
}
// after
import ForwardEmail from "@auth/core/providers/forwardemail"
providers: [
  ForwardEmail({
    apiKey: process.env.FORWARD_EMAIL_API_KEY, // must be set
    from: "no-reply@your-verified-domain.com",
  })
]
Defensive patterns

Strategy: try-catch

Validate before calling

if (!process.env.FORWARD_EMAIL_API_KEY) throw new Error('FORWARD_EMAIL_API_KEY is not set')
if (!provider.from?.includes('@')) throw new Error('ForwardEmail provider.from must be a full email address')

Type guard

function isForwardEmailConfigured(p: { apiKey?: string; from?: string }): p is { apiKey: string; from: string } {
  return typeof p.apiKey === 'string' && p.apiKey.length > 0 && !!p.from?.includes('@')
}

Try / catch

try {
  await sendVerificationRequest(params)
} catch (e) {
  const msg = e instanceof Error ? e.message : String(e)
  console.error('Forward Email send failed:', msg) // msg embeds the API JSON body
  // surface a generic 'could not send email' to the user; do not leak internals
}

Prevention

When it happens

Trigger: Forward Email's POST /v1/email endpoint returns 4xx/5xx during sendVerificationRequest — e.g. invalid/missing FORWARD_EMAIL_API_KEY, unverified sending domain, malformed message, or rate limiting. Any res.ok === false triggers the throw with the API's JSON body embedded in the message.

Common situations: Developers hit this when the API key env var is unset or revoked, the 'from' domain is not verified in Forward Email, or during outages/rate limits. It often surfaces only at first sign-in attempt because the provider does no upfront credential validation.

Related errors


AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28). Data as JSON: /api/errors/d067d10bf34460e4. Report an issue: GitHub.