nextauthjs/next-auth · error · InvalidCheck

State data was provided but the provider is not configured…

Error message

State data was provided but the provider is not configured to use state

What it means

state.create throws InvalidCheck when an `origin`/state body was supplied to encode into the state cookie, but the provider's `checks` array does not include "state". The library only stores state data for providers opted into the state check, so passing state data otherwise is treated as a config inconsistency.

Solutions

  1. Add "state" to the provider's checks array: checks: ["state"] (optionally alongside "pkce").
  2. Or stop passing state/origin data for providers that don't use the state check.
  3. Review custom provider definitions to ensure the checks array matches the features you use.

Example fix

// before
const Provider = {
  id: "custom",
  type: "oauth",
  checks: ["pkce"],
  // ...
}
// after
const Provider = {
  id: "custom",
  type: "oauth",
  checks: ["state", "pkce"],
  // ...
}
Defensive patterns

Strategy: validation

Validate before calling

const checks = providerConfig.checks ?? []
if (wantsStateData && !checks.includes("state")) {
  throw new Error("Add 'state' to provider checks before passing state data")
}

Type guard

function supportsState(p: { checks?: string[] }): boolean {
  return (p.checks ?? []).includes("state")
}

Prevention

When it happens

Trigger: Calling signIn or a provider flow with custom state/redirect data (e.g. authorization params callbackUrl encoded in state) while the provider config lacks checks: ["state"] (or has only ["pkce"]/["nonce"]).

Common situations: Custom OAuth provider definitions copied without `checks: ["state"]` while the app passes extra state; switching provider type from oidc to oauth and dropping the checks array; programmatic signIn calls passing origin but misconfigured provider.

Related errors


AI-assisted analysis of nextauthjs/next-auth@a1a16a5a77 (2026-08-28). Data as JSON: /api/errors/da25fd7a762ae6c0. Report an issue: GitHub.

Appendix: source

Thrown at packages/core/src/lib/actions/callback/oauth/checks.ts:162

interface EncodedState {
  origin?: string
  random: string
}

const STATE_MAX_AGE = 60 * 15 // 15 minutes in seconds
const encodedStateSalt = "encodedState"

/**
 * @see https://www.rfc-editor.org/rfc/rfc6749#section-10.12
 * @see https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
 */
export const state = {
  /** Creates a state cookie with an optionally encoded body. */
  async create(options: InternalOptions<"oauth">, origin?: string) {
    const { provider } = options
    if (!provider.checks.includes("state")) {
      if (origin) {
        throw new InvalidCheck(
          "State data was provided but the provider is not configured to use state"
        )
      }
      return
    }

    // IDEA: Allow the user to pass data to be stored in the state
    const payload = {
      origin,
      random: o.generateRandomState(),
    } satisfies EncodedState
    const value = await encode({
      secret: options.jwt.secret,
      token: payload,
      salt: encodedStateSalt,
      maxAge: STATE_MAX_AGE,
    })
    const cookie = await sealCookie("state", value, options)

View on GitHub (pinned to a1a16a5a77)