{"record":{"id":"5cf45d70bc23da12","repo":"nextauthjs/next-auth","slug":"mailgun-error-await-res-text","errorCode":null,"errorMessage":"Mailgun error: + (await res.text())","messagePattern":"Mailgun error: \\+ \\(await res\\.text\\(\\)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/providers/mailgun.ts","lineNumber":94,"sourceCode":"\n      if (!domain) throw new Error(\"malformed Mailgun domain\")\n\n      const form = new FormData()\n      form.append(\"from\", `${provider.name} <${provider.from}>`)\n      form.append(\"to\", to)\n      form.append(\"subject\", `Sign in to ${host}`)\n      form.append(\"html\", html({ host, url, theme }))\n      form.append(\"text\", text({ host, url }))\n\n      const res = await fetch(`https://${apiServer}/v3/${domain}/messages`, {\n        method: \"POST\",\n        headers: {\n          Authorization: `Basic ${btoa(`api:${provider.apiKey}`)}`,\n        },\n        body: form,\n      })\n\n      if (!res.ok) throw new Error(\"Mailgun error: \" + (await res.text()))\n    },\n    options: config,\n  }\n}\n","sourceCodeStart":76,"sourceCodeEnd":99,"githubUrl":"https://github.com/nextauthjs/next-auth/blob/a1a16a5a7780488c7449feece410033f445d0b31/packages/core/src/providers/mailgun.ts#L76-L99","documentation":"Thrown when Mailgun's messages API returns a non-OK status after the multipart form was sent. The provider includes Mailgun's raw response text (usually JSON or HTML error output) in the message. This means the request reached Mailgun but was rejected — authentication, domain, or payload problems — so no verification email was delivered.","triggerScenarios":"POST to https://api.mailgun.net (domain-derived endpoint) with Basic auth api:API_KEY returns 401 (bad key), 400 (bad form field / unverified domain / sandbox domain not authorized for recipient), 402/429 (limits), or 5xx. The check `if (!res.ok)` triggers the throw with the response text.","commonSituations":"Wrong or revoked MAILGUN_API_KEY; sending from an unverified domain; using the EU vs US host mismatch; trying to send to un-authorized recipients on a Mailgun sandbox domain in test mode.","solutions":["Inspect the response text in the error — Mailgun states the rejection reason","Verify MAILGUN_API_KEY is the private API key of the correct Mailgun account and region (EU endpoints need the EU base URL)","Confirm the sending domain is verified in Mailgun and matches the domain parsed from provider.from","If on a sandbox domain, add the recipient to Mailgun's Authorized Recipients list"],"exampleFix":"// before\nMailgun({ apiKey: process.env.MAILGUN_API_KEY }) // key from old account -> 401\n// after\n// use the correct regional key + verified domain\nMailgun({\n  apiKey: process.env.MAILGUN_API_KEY,\n  from: \"Auth.js <no-reply@mg.your-verified-domain.com>\",\n})","handlingStrategy":"try-catch","validationCode":"if (!process.env.MAILGUN_API_KEY) throw new Error('MAILGUN_API_KEY is not set')\nif (!/^[^\\s@]+@[^\\s@]+$/.test(provider.from ?? '')) throw new Error('Mailgun from must be a valid address on a verified domain')","typeGuard":"function isMailgunConfigured(p: { apiKey?: string; from?: string }): p is { apiKey: string; from: string } {\n  return !!p.apiKey && !!p.from && p.from.includes('@')\n}","tryCatchPattern":"try {\n  await sendVerificationRequest(params)\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e)\n  if (msg.includes('401')) console.error('Mailgun auth failed: check MAILGUN_API_KEY')\n  else console.error('Mailgun send failed:', msg) // response text has the reason\n}","preventionTips":["Use the correct private API key for your account's region (US/EU base URL)","Verify the sending domain in Mailgun and keep provider.from on it","On sandbox domains, pre-authorize recipient addresses","Inspect res.text() output in the error message — Mailgun reports the exact reason"],"tags":["email","http-error","mailgun","api-error"],"backgroundTag":"email-api-http-error","analyzedSha":"a1a16a5a7780488c7449feece410033f445d0b31","analyzedAt":"2026-08-28T21:52:38.200Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}