Conversion

Why do my magic link logins fail?

By Jake Luo · Published Aug 26, 2026

Most magic-link failures are not your user's fault and not a delivery problem: something opened the link before the human did. Email security scanners, link-preview bots and inbox prefetchers follow every URL in a message within seconds of delivery, and if your token dies on first use, that automated fetch spends it — so the real click lands on "this link has already been used". The fix is to let expiry, not first open, end a link's life, and to always leave a second way in.

The failure that looks like a user error

The symptom is always the same and always confusing. Someone asks for a login link, the link arrives, they click it, and your app tells them it is invalid or already used. Nothing in your logs looks broken: the mail was accepted, the token was created, and the token was verified. It was verified — just not by the person you sent it to. Between your send and their click there is a queue of machines reading that message: the recipient's mail-security product rewriting and following links to check them, the mail client prefetching so a preview renders instantly, corporate gateways detonating URLs in a sandbox, and sometimes a filter doing the same on the way in.

We hit this in our own production signup flow in August 2026, and the shape of it is worth repeating because it looked like nothing. One signup requested three links in a single sitting. All three were verified server-side within 16 to 23 seconds of being sent — far too fast to be a person reading an inbox — and every human click after that was rejected as already used. They only got in by starting again with a social sign-in. Two ordinary habits make it worse and produce the identical log line: people request a link on their phone and open it on their laptop, and people forward a login mail to a colleague or to their own second address. If your design assumes the first request for a token is the human's browser, all three of these read as an attack when they are the normal case.

Work out which one is yours

Before changing anything, find out what actually spent the token. The timestamp is the tell: a scanner or a prefetcher lands within seconds of the send, a person lands in tens of seconds to minutes. Log the time, user agent and IP of every verification next to the time of the send, then read them together.

What you seeLikely causeHow to confirm it
Verified seconds after send, the human click then rejectedA mail-security scanner or an inbox prefetcher opened it firstCompare the verification timestamp with the send; check whether the user agent and IP belong to a mail provider rather than a browser
Fails only for people at one companyThat company's mail gateway is rewriting and detonating linksAsk the user to paste the link back to you and look for a rewritten host in it
Requested on a phone, fails on a laptopThe token is bound to the browser session that requested itWalk the flow yourself across two devices before blaming anything else
Fails only after a long gap, with no early verificationThe link genuinely expired — often a short lifetime plus a slow inboxMeasure the gap between send and click against your own expiry window
Never arrives at allA deliverability problem, not a token problemCheck bounces, spam placement and your sending domain's authentication records first

The fix, in the order that matters

The order is load-bearing, because two of these steps are safe on their own and dangerous in the wrong sequence.

  1. Check expiry before you consume An expired token must never be able to open a session, whatever else you change. Putting the expiry check first is what makes the next step safe — without it, tolerating a repeat open would extend a link's life instead of merely surviving an extra visit.
  2. Let an unexpired link be opened more than one time Accept a token that has already been verified but is still inside its lifetime, and return a flag saying so rather than an error. A link should die when it expires, not when the first machine touches it.
  3. Keep the first verification timestamp When you accept a repeat open, do not overwrite the original consumed-at time. It is the only record of which visit actually won, and it is the first thing you will want the next time somebody reports this.
  4. Shorten the window instead of narrowing the opens A short-lived link that tolerates several visits is safer in practice than a long-lived one that dies on first touch. The short lifetime is doing the security work; single use was only ever a proxy for it.
  5. Always leave a second door Offer one other way in — a password, a passkey, or a social sign-in — and show it on the failure screen itself, not three clicks away. The signup we lost to this recovered through social sign-in; without that door it would have been gone at the threshold.
  6. Say something useful when it does fail "Invalid link" tells someone they did something wrong. "This link has expired — here is a fresh one", with a one-tap resend on the same screen, keeps them inside the flow instead of sending them to your support inbox.

The part that never shows up as a bug

The login failure is visible. The measurement damage is not, and it outlives the bug. If your signup conversion event fires on the first request that reaches your verification endpoint, then whenever a scanner gets there first the conversion rides a redirect that no browser ever executes. That is exactly what happened to us: the brand-new-registration flag travelled with the scanner's request, so the ad-platform signup conversion for that person was never recorded. Anyone bidding on that data is bidding on a number quietly missing some of its hardest-won conversions.

The habit that catches it is dull but reliable: count the completed session, not the link click, and treat the gap between "link requested" and "session created" as its own funnel step. If a real share of requests never becomes a session, no amount of landing-page work will fix it — that is a mechanism failure, not a persuasion failure. See how to turn website visitors into signups for the step before this one and activation rate for the step after. If the mail is not arriving at all, the domain-authentication ladder in how to write cold emails that don't get marked spam applies to transactional mail too. And if you are deciding where that mail should be sent from in the first place, Notifuse is one self-hosted option.

FAQ

How long should a magic link stay valid?
Minutes rather than hours. A short lifetime is what lets you safely tolerate a link being opened more than one time, which is the actual fix. Long-lived single-use links give you the worst of both: they sit in an inbox for hours waiting to be scanned, and they still break on the first machine that touches them.
Should a magic link be single use?
Single use is the wrong unit. What you want is single purpose and short lived: the link signs in exactly one account, and it stops working when it expires. Ending its life at the first open assumes a human's browser gets there first, and frequently nothing gets there first except a scanner.
Why do my logs show the link verified seconds after it was sent?
Because a machine read it. Mail-security products follow links to check them and mail clients prefetch them to render previews, both within seconds of delivery. Compare the verification timestamp with the send time — anything inside a few seconds is almost never a person.
Is this the same as my emails going to spam?
No, and separating them saves you from fixing the wrong thing. Spam placement means the mail never reached the inbox; this means it reached the inbox and the wrong reader opened it. Check bounces and placement first. If the mail is landing, the question becomes who verified the token.
Does this affect my signup analytics?
It can, badly. If your signup conversion fires on the first request to your verification endpoint, a scanner's request can carry it, so the conversion is attributed to a redirect no browser runs or is lost entirely. Fire conversion events on the created session instead, and the problem disappears from your reporting as well as your funnel.
Related questions
How do I turn website visitors into signups?How do I improve user onboarding for my SaaS?How do I write cold emails that don't get marked as spam?

Want this done for you?

AgentCeres is a managed AI marketing team — specialists draft the work, you approve what ships. 14-day free trial, from $39/month.

Start free trialMore answers