Ask
82
@rueben_alsop ·

auth.js google login works on localhost, every vercel preview lands on /api/auth/error OAuth Callback

next-auth v5, Google provider. Works on localhost:3000 and works on the production domain.

On preview deployments it fails two different ways and I cannot work out why it is not consistent. Sometimes Google itself shows "Error 400: redirect_uri_mismatch" before I even pick an account. Sometimes I get the account picker, choose, and get bounced to /api/auth/error with nothing useful on it.

I have added about nine URLs to the authorised redirect list at this point and I am clearly doing this wrong.

9 answers Share
Report

Answering anonymously — a moderator will review it first.

  • @p99_hana · 3h ago · 3 replies

    You are chasing two different bugs, which is why nothing you do fixes both.

    Google's own error screen means the redirect URI in the request is not in your authorised list, exactly. Preview URLs change on every commit, so you will never win this by adding them - you would need a new entry per deploy.

    Getting bounced to your own /api/auth/error means Google was happy and your app rejected the callback. In v5 that is nearly always a missing AUTH_SECRET on the preview environment, or the host check - previews are not the URL you configured, so you need trustHost set for the library to believe the incoming host.

    The real fix for the first one is a proxy: register exactly one stable redirect URI, something like https://auth.yourdomain.com/api/auth/callback/google, and set redirectProxyUrl so previews send the OAuth round trip through that host and get handed back afterwards. One entry in the Google console, forever, regardless of how many branches are open.

    121
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @hemline_hana · 3h ago

      Splitting the two symptoms is the useful part of this thread. Google's screen means the URI. Your error page means your app. Once you know which one you are looking at, both are twenty minutes.

      37
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
    • @thea_mandel · 3h ago

      Also handle the error query param on your error page and print it. The default page is deliberately vague for production and unhelpfully vague for you right now.

      14
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @warranty_wes · 3h ago

    OAuth on preview deployments is a cost centre. We stub it - previews get a dev-only credentials provider behind an env flag that logs you in as a fixture user, and the real Google flow is tested on staging which has one URL that never changes. Two years, zero incidents caused by this, and preview logins take one click.

    28
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @pumptest_pat · 12h ago · 2 replies

    Cheaper version if you are one or two people: your host gives you a stable alias per branch that does not change per commit. Register that one URL for your main working branch and stop thinking about it. It breaks when a third person opens a fourth branch, but it costs five minutes today.

    54
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @stack_trace_sy · 3h ago

      This is the right call at two people and the wrong call at six, and the migration between them is the proxy setup above. Worth knowing which one you are before you build the sophisticated thing.

      20
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @late_stage_phd · 3h ago · 2 replies

    Just add https://*.vercel.app/api/auth/callback/google to the authorised redirect URIs and it covers every preview at once.

    16
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @p99_hana · 3h ago

      Google does not accept wildcards in authorised redirect URIs. Depending on how you enter it you will either get a validation error or it will save and then silently never match anything, which is worse because you will believe it is done.

      This is comfortably the most common wrong answer to this problem and it is worth saying out loud every time.

      13
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @burr_and_edge · 3h ago

    Check whether deployment protection is on for previews. If it is, the callback request from Google gets a 401 from the platform before your route handler ever runs, and the failure looks identical to a misconfigured callback from the outside.

    12
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report