nextjs-auth0: Invalid request, an initial state could not be found

When I try to login, and the auth0 page redirects to the callback url I have this error:

START RequestId: f18c995e-e7e1-4305-a623-3f8cc1f4193c Version: $LATEST
2020-01-03T02:11:45.970Z	f18c995e-e7e1-4305-a623-3f8cc1f4193c	ERROR	Error: Invalid request, an initial state could not be found
    at Object.<anonymous> (/var/task/node_modules/@auth0/nextjs-auth0/dist/handlers/callback.js:18:19)
    at Generator.next (<anonymous>)
    at /var/task/node_modules/tslib/tslib.js:110:75
    at new Promise (<anonymous>)
    at Object.__awaiter (/var/task/node_modules/tslib/tslib.js:106:16)
    at Object.handleCallback (/var/task/node_modules/@auth0/nextjs-auth0/dist/handlers/callback.js:6:43)
    at callback (/var/task/.next/serverless/pages/api/user/callback.js:127:70)
    at apiResolver (/var/task/node_modules/next/dist/next-server/server/api-utils.js:41:9)
    at process._tickCallback (internal/process/next_tick.js:68:7)
END RequestId: f18c995e-e7e1-4305-a623-3f8cc1f4193c
REPORT RequestId: f18c995e-e7e1-4305-a623-3f8cc1f4193c	Duration: 473.67 ms	Billed Duration: 500 ms	Memory Size: 1024 MB	Max Memory Used: 94 MB	Init Duration: 202.36 ms	

START RequestId: e8146182-4fb9-47f8-bb34-04053eb80d0a Version: $LATEST
END RequestId: e8146182-4fb9-47f8-bb34-04053eb80d0a
REPORT RequestId: e8146182-4fb9-47f8-bb34-04053eb80d0a	Duration: 81.24 ms	Billed Duration: 100 ms	Memory Size: 1024 MB	Max Memory Used: 97 MB	Init Duration: 422.52 ms	

This is the code I’m using for the Login url:

import { NextApiRequest, NextApiResponse } from "next";

import auth0 from "../../../lib/auth0";

async function login(req: NextApiRequest, res: NextApiResponse) {
  try {
    await auth0.handleLogin(req, res, {});
  } catch (error) {
    console.error(error);
    res.status(error.status || 500).end(error.message);
  }
}

export default login;

This is the code from the Callback and where the error comes:

import { NextApiRequest, NextApiResponse } from "next";

import auth0 from "../../../lib/auth0";

async function callback(req: NextApiRequest, res: NextApiResponse) {
  try {
    await auth0.handleCallback(req, res, { redirectTo: "/" });
  } catch (error) {
    console.error(error);
    res.status(error.status || 500).end(error.message);
  }
}

export default callback;

The Auth0 file that in each function I’m importing is this:

import { initAuth0 } from "@auth0/nextjs-auth0";

export default initAuth0({
  clientId: process.env.AUTH0_CLIENT_ID,
  clientSecret: process.env.AUTH0_CLIENT_SECRET,
  scope: process.env.AUTH0_SCOPE,
  domain: process.env.AUTH0_DOMAIN,
  redirectUri: process.env.REDIRECT_URI,
  postLogoutRedirectUri: process.env.POST_LOGOUT_REDIRECT_URI,
  session: {
    cookieSecret: process.env.SESSION_COOKIE_SECRET,
    cookieLifetime: parseInt(process.env.SESSION_COOKIE_LIFETIME),
    storeIdToken: true,
    storeRefreshToken: true,
    storeAccessToken: true
  }
});

And the variables are configured like this (from the now.json file):

{
  "version": 2,
  "build": {
    "env": {
      "MONGODB_URI": "mongodb://test:test@ds1234.mlab.com:1234/test",
      "AUTH0_DOMAIN": "dev-98h51dru.auth0.com",
      "AUTH0_CLIENT_ID": "",
      "AUTH0_CLIENT_SECRET": "",
      "AUTH0_SCOPE": "openid profile offline_access",
      "REDIRECT_URI": "https://tevi.now.sh/api/user/callback",
      "POST_LOGOUT_REDIRECT_URI": "https://tevi.now.sh/",
      "SESSION_COOKIE_SECRET": "",
      "SESSION_COOKIE_LIFETIME": "28800"
    }
  }
}

You can test the app here.

This error happens when is in production with Now, and in development mode, with the command now dev (http://localhost:3000/)

The config in the Auth0 Application is this:

Allowed Callback Urls: http://localhost:3000/api/user/callback, https://tevi.now.sh/api/user/callback Allowed Web Origins: http://localhost:3000/, https://tevi.now.sh/ Allowed Logout URLs: http://localhost:3000/, https://tevi.now.sh/ Allowed Origins (CORS): http://localhost:3000/, https://tevi.now.sh/

  • Version of this library used: latest
  • Version of the platform or framework used, if applicable: Next.js latest version and Now Api
  • Other relevant versions (language, server software, OS, browser): TypeScript, Linux, Firefox and Chrome latest version

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 9
  • Comments: 37 (3 by maintainers)

Most upvoted comments

I set up my login route at /login/auth0 and my callback route at /oauth2/callback and ran into this same error. Turns out the cookiePath is not set in the login handler so those cookies exist at the directory above the current uri according to the algorithm defined by RFC 6265 causing my state cookie to be stored at the path /login and hence not sent to the callback route causing Error: Invalid request, an initial state could not be found. I’m not sure if this is by design or a bug but it seems counterintuitive that the state cookie should not exist at the same path as the session and redirect cookie. Also, the fragility surrounding the fact that the login handler route must be a parent or sibling of the callback route should probably be documented.

In my case it was : https://nextjs.org/docs/api-reference/next.config.js/trailing-slash I have to set trailingSlash: false

After some debugging I found the same as @alex-windett. isSecureEnvironment() causes Secure to be added to the Set-Cookie header.

This means you must either use HTTPS or set NODE_ENV to something different than production when using a host that’s not localhost or 127.0.0.1.

NODE_ENV=development solved the issue for me.

I see “Error: Invalid request, an initial state could not be found” in my logs in the catch of /api/callback.js but it is infrequent so I can’t figure out why it is happening to some users.

It seems like this can also be caused by having more than ~512b of custom claims and/or user_metadata in the ID token returned to auth0. (I didn’t verify the exact number, but it seems to happen somewhere around there.)

This project sets the session information in a cookie called a0:session, which includes the access_token, id_token, refresh_token, scopes, user object, and created_at. If the encoded size of that (plus the cookie metadata) exceeds 4k, the browsers will drop it, and your session won’t get started, then the redirect loop causes an attempt to login with a different state.

There is no current method in this library to store the session anywhere but in the cookie, unfortunately.