Could not load PKCE codeVerifier from storage and callback stuck on loadingElement

We have had reports of subsets of users (for a given customer, some can sign in, some can’t) of our web application either:

  1. Signing in and getting the error “Could not load PKCE codeVerifier from storage”
  2. Being left on /callback with the loadingElement perpetually displayed, with no redirect to the origin URL taking place.
  3. Clicking on the Sign In button and nothing happening

And we’re unable to reproduce any issues ourselves and so are looking for any recommendations from the experts to assist with our investigation and resolution.

For context, we have a Next.js 12 application using:

    "@okta/jwt-verifier": "^3.0.1",
    "@okta/okta-auth-js": "^7.2.0",
    "@okta/okta-react": "^6.7.0",

Our configuration is:

export const oktaConfig = new OktaAuth({
  clientId: `${CLIENT_ID}`,
  issuer,
  redirectUri,
  scopes: ['openid', 'email', 'profile'],
  pkce: true,
  storageManager: {
    token: {
      storageTypes: ['cookie'],
    },
    cache: {
      storageTypes: ['localStorage', 'cookie'],
    },
    transaction: {
      storageTypes: ['cookie'],
    },
  },
  tokenManager: {
    autoRenew: true,
  },
  postLogoutRedirectUri,
});

Our /callback page includes this component:

import React from 'react';
import { LoginCallback } from '@okta/okta-react';
import Loading from '../shared/components/loading/loading';
import ComposedPageLayout from '../shared/components/layout/composed-page-layout';
import ErrorComponent from '../auth/components/errorComponent';

const loadingElement = React.createElement(Loading);

const ImplicitCallback = (): any => {

  return (
    <ComposedPageLayout>
        <LoginCallback
          errorComponent={ErrorComponent}
          loadingElement={loadingElement}
        />
    </ComposedPageLayout>
  );
};

export default ImplicitCallback;

The Sign In button being defined as:

<Button
              handleButtonClick={() => onLogin(appAuthService!, router)}
            >
              Sign in
            </Button>

And the onLogin function being defined as:

import type { NextRouter } from 'next/router';
import type { ParsedUrlQuery } from 'querystring';
import URI from 'urijs';
import type AppAuthService from '../services/auth-service';

function getRedirectUrl(query: ParsedUrlQuery): string | undefined {
  if (query.redirect) {
    return URI(query.redirect as string).toString();
  }
  if (query.state) {
    return URI(query.state as string).toString();
  }
  return undefined;
}

export const onLogin = (
  appAuthService: AppAuthService,
  router: NextRouter
): void => {
    appAuthService.login(getRedirectUrl(router.query));
};

The user journey is:

  1. Navigate to /login
  2. Click “Sign In” button
  3. This triggers an login event which takes the browser to: https://okta.customdomain.tld/oauth2/<id>/v1/authorize?client_id=<client-id>&code_challenge=<code>&code_challenge_method=S256&nonce=<nonce>&redirect_uri=https%3A%2F%2Four.domain.com%2Fcallback&response_type=code&state=<id>&scope=openid%20email%20profile
  4. After authentication, the browser is returned to https://our.domain.com/callback?code=<code>

I turned on devMode in the oktaAuth configuration, and these events are displayed in the browser logs.

OKTA-AUTH-JS:updateAuthState: Event:undefined Status:emitted
undefined undefined
Current authState {accessToken: undefined, idToken: undefined, refreshToken: undefined, isAuthenticated: false}
OKTA-AUTH-JS:updateAuthState: Event:added Status:canceled
accessToken {accessToken: '<token>', claims: {…}, expiresAt: 1715131266, tokenType: 'Bearer', scopes: Array(3), …}
Current authState {accessToken: undefined, idToken: undefined, refreshToken: undefined, isAuthenticated: false}
OKTA-AUTH-JS:updateAuthState: Event:undefined Status:canceled
undefined undefined
Current authState {accessToken: undefined, idToken: undefined, refreshToken: undefined, isAuthenticated: false}
OKTA-AUTH-JS:updateAuthState: Event:undefined Status:emitted
undefined undefined
Current authState {accessToken: {…}, idToken: {…}, refreshToken: undefined, isAuthenticated: true}

I have looked at : Could not load PKCE codeVerifier from storage - #2 by andrea but the conversation was inconclusive.

Does anyone have any insight into why any of the three issues we’re seeing reported may be happening, or how to debug?

  1. Signing in and getting the error “Could not load PKCE codeVerifier from storage”
  2. Being left on /callback with the loadingElement perpetually displayed, with no redirect to the origin URL taking place.
  3. Clicking on the Sign In button and nothing happening

Facing same issue. Any resolution found

No direct solution. Okta Support recommended it was likely a race condition or redirect, so we spent a lot of time trying to identify how that might occur and tried a few things about our app behaviour that seems to have reduced the frequency of occurrence.