nextauthjs/next-auth · error · AccountNotLinked
Another account already exists with the same e-mail address
Error message
Another account already exists with the same e-mail address
What it means
An AccountNotLinked error thrown during sign-in when the user is not signed in, no existing user matches the provider account, but the profile's email already belongs to an existing user. Auth.js does not trust user-supplied emails, so it refuses to auto-link, throwing at handle-login.ts:192.
Source
Thrown at packages/core/src/lib/actions/callback/handle-login.ts:192
await linkAccount({ ...account, userId: user.id })
await events.linkAccount?.({ user, account, profile })
// As they are already signed in, we don't need to do anything after linking them
const currentAccount: AdapterAccount = { ...account, userId: user.id }
return { session, user, isNewUser, account: currentAccount }
}
// If the user is not signed in and it looks like a new account then we
// check there also isn't an user account already associated with the same
// email address as the one in the request.
const userByEmail = profile.email
? await getUserByEmail(profile.email)
: null
if (userByEmail) {
// We don't trust user-provided email addresses, so we don't want to link accounts
// if the email address associated with the new account is already associated with
// an existing account.
throw new AccountNotLinked(
"Another account already exists with the same e-mail address",
{ provider: account.provider }
)
} else {
// If the current user is not logged in and the profile isn't linked to any user
// accounts (by email or provider account id)...
//
// If no account matching the same [provider].id or .email exists, we can
// create a new account for the user, link it to the OAuth account and
// create a new session for them so they are signed in with it.
user = await createUser({ ...profile })
}
await events.createUser?.({ user })
await linkAccount({ ...account, userId: user.id })
await events.linkAccount?.({ user, account, profile })
session = useJwtSessionView on GitHub (pinned to a1a16a5a77)
Solutions
- Set allowDangerousEmailAccountLinking: true on the provider if you verify emails yourself and accept the risk.
- Have the user first sign in with the original method, then link the OAuth account from the account settings.
- Manually insert the account row linking the provider account to the existing user (or expose a link-account flow).
- Ensure the provider returns email_verified so verified-email linking can be considered where supported.
Example fix
// before
GitHub({ clientId: process.env.GITHUB_ID, clientSecret: process.env.GITHUB_SECRET })
// after
GitHub({ clientId: process.env.GITHUB_ID, clientSecret: process.env.GITHUB_SECRET, allowDangerousEmailAccountLinking: true }) Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check in your sign-in page:
const userByEmail = await adapter.getUserByEmail(profile.email)
if (userByEmail && !allowDangerousEmailAccountLinking) {
// show 'account exists — sign in with your original method to link'
} Try / catch
try {
await signIn('google')
} catch (e) {
if (e instanceof AccountNotLinked) {
// prompt user to sign in with the original method and link there
}
} Prevention
- Enable allowDangerousEmailAccountLinking only when the provider verifies emails and you accept the risk.
- Prefer an explicit 'link account' flow while the user is authenticated.
- Avoid shared inboxes as registered emails.
- Return email_verified from custom providers when the IdP verifies addresses.
When it happens
Trigger: First-time OAuth sign-in where the OAuth profile email equals the email of an already-registered user (e.g. registered via email/magic link earlier), with allowDangerousEmailAccountLinking disabled and no account row linking them.
Common situations: User registered by email link previously and later tries to sign in with Google using the same address; providers (like some enterprise IdPs) where emails are not verified; shared/role inboxes (support@company.com) used by multiple login methods.
Related errors
- The account is already associated with another user
- Verification
- Account not found
- Account not created
- Must pass `secret` if not set to JWT getToken()
AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28).
Data as JSON: /api/errors/39ee61097cea78aa.
Report an issue: GitHub.