BadRequestError: checks.state argument is missing

Hey All,

I find that every so often(not sure of the exact cadence for this error) I get the following error after the user is successfully authenticated(i.e. the url this is happening on is https://website.com/callback):

BadRequestError: checks.state argument is missing:
at /var/www/app/html/node_modules/express-openid-connect/middleware/auth.js:94:29 
at processTicksAndRejections (internal/process/task_queues.js:97:5)

I am using express-openid-connect v1.0.1 and the new Universal Login page. Interestingly I never run into this when testing locally, only on the server if that context helps.

Update 1: Another piece of the puzzle. When I get the above error and then go back to https://website.com/ and click sign in again, authentication and redirect works flawlessly without me even seeing the universal login screen.

From this point, I can logout and login to my heartā€™s content without seeing the error again.

Update 2: Thought it might be something to do with cookies and the fact that the Express server runs behind Nginx and so I added:

app.use("trust proxy", true);

Still the same problem :frowning:

Update 3: I can now see that the first time I authenticate and get the error as described there is no cookie set on the domain. Once I go back to the landing page and attempt authentication again, the appSession cookie is set and persists so, from there on out(as mentioned before) sign in and sign out works as expected.

Any idea why setting the cookie the first time would fail? But then succeed on the second attempt? Is this a possible bug in the connect node module?

Has anyone else run into this problem? Any ideas on a resolution? Thank you

1 Like

I very much looks to me like this is the root of the problem here:

If youā€™re a customer of Auth0, then be sure weā€™re already executing steps necessary to facilitate this change. Some changes will happen automatically, on Auth0ā€™s side, without requiring any action on yours. Depending on the particular SDK and underlying grant your web app is using to implement Sign-In and/or Authorization, you might need to update to a newer version of the SDK capable of handling the new browser behavior.

Check and update your SDKs periodically, and be on the lookout for any advisories in their README and CHANGELOG as well as your Auth0 Dashboard Notifications for any actions required.

Will have to see whether express-openid-connect handles this correctly. Still odd why it works on the second and all subsequent attempts

Suggests that all is good, but seems I am still being affected.


I guess the immediate possible solution is to use server side sessions with express-session and reddis. I am going to look into this and will report whether this solves the problem.

So, it seems like the core of this problem was caused by an HTTP call somewhere in between the HTTPS calls during the roundtrip. So, as soon as the HTTP call is made, the cookie is dropped because cookie.secure is set to true.

Setting cookie.secure to false, solved the problem. Now to figure out where the HTTP call happens. The origin site runs via HTTPS and everything is forced to be via HTTPS so, not sure if it could still happen(I guess it can), or whether this is on theAuth0 side somewhere.

1 Like

Also seeing this issue. In my network requests I see http://auth0.com is trying to set a cookie? Wonder if this issue is on the auth0 side?

1 Like

It will 100% cause the issue. I noticed this as well in Safari as it throws up a notice saying the page is not secure. If I remember correctly the title of that page is something like ā€œSubmit this formā€.

So yes, if cookie = secure is set and anywhere along the flow there is an HTTP call, the cookie will be dropped.

The error is accompanied by either an HTTP 400 Bad Request error or an but during this period API responses might reflect the inconsistent state of the table.

Hey @schalk.neethling I believe this is fixed in Release v1.0.2 Ā· auth0/express-openid-connect Ā· GitHub from Cookie options should be applied when clearing the cookie as well as setting the cookie by adamjmcgrath Ā· Pull Request #94 Ā· auth0/express-openid-connect Ā· GitHub

Can you try that version and if that doesnā€™t resolve your issue can you provide some more details about your implementation?

  • What is in your config that you pass into the auth middleware for prod vs. dev?
  • Are you running your local server on http or https?
  • Can you attach a HAR file of the exchange? Generate and Analyze HAR Files
2 Likes

Hi wanted to bump this as Iā€™m getting the same issue still. Iā€™ve updated my version of express-openid-connect.
Users on iPhone seem to not experience this issue. Though Android and windows chrome for sure are.

Hey David, thank you for the heads up and apologies for taking so long to reply. I have moved back to the previous passport.js solution that Auth0 used to suggest for the project in question.

I am curious about using the new shiny module though so, I am thinking I will build a skeleton auth project to try it out. I will let you know if I still run into the same problem. Also note, when running locally I do not see the error as I do not set cookie to secure=true

This only happens in production.

Iā€™m experiencing this issue using the auth0/nextjs package. I have a live url where authentication works perfectly fine but on hosted development urls, I received the checks.state argument is missing error. Do you think this error could be related to the actual URL? Or could it be related to environment variables? I have set up the same environment variables to test that theory but still no luck getting past the issue on developement urls

4 Likes

Iā€™m receiving this error as well using that package. I just dropped an issue in github. Everything works great for me in every browser except Safari both on localhost and hosted on vercel.

I think it might be. It worked for me on localhost, but when I deployed it to Vercel, trying to sign in triggers this for me.

The problem started when I did the major version upgrade to 1.1.0.

Yeah, I was able to get past it on my deployed production URL by re-entering my environment variables but when Vercel auto deploys on a PR - with a sort of https://<regular-url>-<random-url>.vercel.app - I receive this error. My environment variables are all set for development and production so I feel like it has to do with the callback urls within Auth0.

Iā€™ve attempted things like https://<regular-url>* and https://*.vercel.app but neither have worked. I even put a full url that was created with a PR auto deploy and it still didnā€™t work so Iā€™m unsure what to try next.

3 Likes

hi, have you guys solved this problem ? Iā€™m having it when deploying in Netlifyā€¦
Thanks for any hint!

Yeah, Iā€™m seeing this problem too. No idea whatā€™s going on :frowning:

Same problem here as well, became noticeable once I tried adding an API with authentication protected routes as well, the login button throws the error.

Hi there !

I really hope my message will help some of you.
After having struggled quite a lot, I finally found what was the origin of the problem in my case :

My website is deployed on Netlify, and Iā€™m using the ā€˜@auth0/nextjs-auth0ā€™ dependenciy. Locally, Iā€™m using netlify cli to test it, with the ā€˜netlify devā€™ command instead of the default Next.js command ā€˜npm run devā€™.

While with ā€˜npm run devā€™ the environment variables are read from the .env.local file, using ā€˜netlify devā€™ the environment variables are directly injected from the production dashboard environment variables, causing this issue because it brings the AUTH_BASE_URL from production.

In order to ignore the production ones (or override them when testing locally), I created a .env.development file with a AUTH0_BASE_URL=http://localhost:8888 instead of the AUTH0_BASE_URL=https://.netlify.app, and it works fine!

1 Like

Thanks for sharing that with the rest of community!

I get this error when i use afterCallback as a promise in handleAuth in my Next.js application.

Iā€™m on Next.js canary and auth0/nextjs-auth0 1.3.1

const afterCallback = async (ā€¦, session, ā€¦) {
ā€¦
return session
}

export default handleAuth({
async callback(req, res) {
await handleCallback(req, res, { afterCallback })
}
})

1 Like