Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/auth0/nextjs-auth0/llms.txt

Use this file to discover all available pages before exploring further.

This guide provides solutions for common issues you may encounter when using the Auth0 Next.js SDK.

Authentication Issues

Infinite redirect loop

Symptoms: Browser keeps redirecting between /auth/login and /auth/callback. Causes & Solutions:
Ensure your callback URL is registered in the Auth0 Dashboard:
  1. Go to Applications
  2. Select your application
  3. Add your callback URL to Allowed Callback URLs:
    • Local: http://localhost:3000/auth/callback
    • Production: https://yourdomain.com/auth/callback
  4. Add your logout URL to Allowed Logout URLs:
    • Local: http://localhost:3000
    • Production: https://yourdomain.com
If your middleware matcher excludes /auth/* routes, authentication won’t work.
// Wrong - excludes auth routes
export const config = {
  matcher: ["/dashboard/:path*"]
};

// Correct - includes all routes except static files
export const config = {
  matcher: [
    "/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)"
  ]
};
If using Next.js basePath, ensure NEXT_PUBLIC_BASE_PATH is set:
NEXT_PUBLIC_BASE_PATH=/dashboard
Auth routes will be at /dashboard/auth/login, /dashboard/auth/callback, etc.

”Invalid state” error

Error code: invalid_state Causes & Solutions:
Large time differences can cause state validation to fail.Fix: Synchronize system clocks or increase transaction cookie duration:
const auth0 = new Auth0Client({
  transactionCookie: {
    duration: 900 // 15 minutes instead of default 10
  }
});
Multiple tabs or windows attempting login simultaneously.Fix: Ensure enableParallelTransactions is enabled (default):
const auth0 = new Auth0Client({
  enableParallelTransactions: true // Default, supports concurrent flows
});

Session not persisting after login

Symptoms: User successfully logs in but getSession() returns null. Causes & Solutions:
If your beforeSessionSaved hook throws an error, the session won’t be saved.Fix: Add error handling:
const auth0 = new Auth0Client({
  beforeSessionSaved: async (session) => {
    try {
      // Your custom logic
      return session;
    } catch (error) {
      console.error("beforeSessionSaved error:", error);
      return session; // Still save the session
    }
  }
});

Token Issues

”Missing refresh token” error

Error code: missing_refresh_token Causes & Solutions:
Refresh tokens require the offline_access scope.Fix:
const auth0 = new Auth0Client({
  authorizationParameters: {
    scope: "openid profile email offline_access"
  }
});
Check your Auth0 Application settings:
  1. Go to Applications
  2. Select your application
  3. Go to Advanced Settings > Grant Types
  4. Enable Refresh Token
Some social providers don’t issue refresh tokens.Check: Auth0 Dashboard > Authentication > SocialWorkaround: Use silent authentication or re-authentication when tokens expire.

Access token expired

Symptoms: API calls fail with 401 Unauthorized. Solutions:
The SDK automatically refreshes tokens server-side if a refresh token is available:
// Automatically refreshes if expired
const { token } = await auth0.getAccessToken();
Refresh tokens slightly before they expire:
const auth0 = new Auth0Client({
  tokenRefreshBuffer: 60 // Refresh 60 seconds before expiry
});
If refresh fails, prompt user to re-authenticate:
import { AccessTokenError, AccessTokenErrorCode } from "@auth0/nextjs-auth0/errors";

try {
  const { token } = await auth0.getAccessToken();
} catch (error) {
  if (error.code === AccessTokenErrorCode.FAILED_TO_REFRESH_TOKEN) {
    redirect("/auth/login");
  }
}

MFA required unexpectedly

Error code: mfa_required Causes & Solutions:
Some API audiences may require MFA even if the user already authenticated.Handle MFA step-up:
import { MfaRequiredError } from "@auth0/nextjs-auth0/errors";

try {
  const { token } = await auth0.getAccessToken({ 
    audience: "https://api.example.com" 
  });
} catch (error) {
  if (error instanceof MfaRequiredError) {
    // Redirect to MFA challenge
    redirect(`/mfa?token=${error.mfa_token}`);
  }
}
Long-lived sessions may trigger MFA re-verification.Check: Auth0 Dashboard > Security > Multi-factor Auth > PoliciesFix: Implement MFA step-up flow in your application.

Configuration Issues

SDK configuration warnings

Symptoms: Console warnings about missing configuration. Solutions:
Ensure all required variables are set:
AUTH0_DOMAIN=your-tenant.us.auth0.com
AUTH0_CLIENT_ID=your-client-id
AUTH0_CLIENT_SECRET=your-client-secret
AUTH0_SECRET=your-32-char-secret
Generate AUTH0_SECRET:
openssl rand -hex 32
Domain should not include protocol or path:
# Wrong
AUTH0_DOMAIN=https://your-tenant.us.auth0.com/

# Correct
AUTH0_DOMAIN=your-tenant.us.auth0.com
For dynamic environments, omit APP_BASE_URL:
// For preview deployments
const auth0 = new Auth0Client();
// SDK infers base URL from request
For static production URLs:
APP_BASE_URL=https://app.example.com

“Discovery failed” error

Error code: discovery_error Causes & Solutions:
Check your domain is correct and accessible:
curl https://YOUR_DOMAIN/.well-known/openid-configuration
Should return OIDC configuration JSON.
Ensure your server can reach Auth0:
  • Check firewall rules
  • Verify DNS resolution
  • Test connectivity: ping your-tenant.us.auth0.com
Increase timeout for slow networks:
const auth0 = new Auth0Client({
  httpTimeout: 10000 // 10 seconds
});

Next.js Specific Issues

Middleware not running

Symptoms: Auth routes don’t work. Solutions:
Next.js 15:
  • File: middleware.ts in project root (or src/middleware.ts if using src/ directory)
Next.js 16:
  • File: proxy.ts in project root (or src/proxy.ts)
  • Note: middleware.ts still works but only on Edge runtime
Ensure matcher includes auth routes:
export const config = {
  matcher: [
    "/((?!_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)"
  ]
};
Only one middleware file is supported. Combine logic:
export async function middleware(request: NextRequest) {
  // Auth0 middleware
  const authResponse = await auth0.middleware(request);
  if (authResponse) return authResponse;
  
  // Your custom middleware
  return customMiddleware(request);
}

Client-side useUser returns undefined

Symptoms: useUser() hook returns undefined after successful login. Solutions:
Wrap your app with Auth0Provider:
// app/layout.tsx
import { Auth0Provider } from "@auth0/nextjs-auth0/client";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Auth0Provider>
          {children}
        </Auth0Provider>
      </body>
    </html>
  );
}
useUser is a client hook. Use getSession in Server Components:
// Server Component
import { auth0 } from "@/lib/auth0";

export default async function Page() {
  const session = await auth0.getSession();
  // ...
}
// Client Component
"use client";
import { useUser } from "@auth0/nextjs-auth0/client";

export function UserProfile() {
  const { user } = useUser();
  // ...
}

Build errors with DPoP

Symptoms: Build fails when using DPoP features. Solutions:
DPoP requires Node.js runtime. Configure route segment:
// app/api/route.ts
export const runtime = "nodejs"; // Not "edge"
CryptoKey objects can’t be serialized. Load keys at runtime:
// Don't do this at module level
const dpopKeyPair = await generateKeyPair("ES256");

// Do this - use environment variables
const auth0 = new Auth0Client({
  useDPoP: true
  // Keys loaded from AUTH0_DPOP_PUBLIC_KEY and AUTH0_DPOP_PRIVATE_KEY
});

Performance Issues

Slow authentication

Solutions:
Reuse OIDC discovery and JWKS:
// Auth0Client caches discovery by default
// Ensure you're instantiating once and reusing

// lib/auth0.ts
export const auth0 = new Auth0Client();
  • Remove unnecessary scopes
  • Use shorter custom claim names
  • Avoid large custom claims
Store session data in Redis/database instead of cookies:
const auth0 = new Auth0Client({
  sessionStore: new RedisSessionStore()
});

High memory usage

Solutions:
Create a single instance and reuse:
// Good - lib/auth0.ts
export const auth0 = new Auth0Client();

// Bad - creating new instance per request
export function getAuth0() {
  return new Auth0Client();
}
Reduces session writes:
const auth0 = new Auth0Client({
  session: {
    rolling: false
  }
});
Note: This may impact security. See Session Configuration.

Debugging Tips

Check browser console and server logs:
// Add logging in hooks
const auth0 = new Auth0Client({
  beforeSessionSaved: async (session) => {
    console.log("Saving session:", session);
    return session;
  },
  onCallback: async (req, session, state) => {
    console.log("Callback:", { session, state });
    return { session };
  }
});
Use browser DevTools:
  1. Open DevTools > Application/Storage
  2. Look for cookies:
    • Session: appSession (default name)
    • Transaction: auth_verification
  3. Check size, expiry, flags (HttpOnly, Secure, SameSite)
View authentication logs in Auth0 Dashboard:
  1. Go to Monitoring > Logs
  2. Filter by application
  3. Look for failed login attempts, errors
Test discovery endpoint:
curl https://YOUR_DOMAIN/.well-known/openid-configuration
Verify:
  • authorization_endpoint
  • token_endpoint
  • jwks_uri
  • Supported grant_types

Getting Help

If you’re still experiencing issues:
  1. Check existing issues: GitHub Issues
  2. Search documentation: Auth0 Docs
  3. Ask the community: Auth0 Community
  4. Report bugs: New Issue
When reporting issues, include:
  • SDK version (@auth0/nextjs-auth0 version)
  • Next.js version
  • Node.js version
  • Minimal reproduction code
  • Error messages with stack traces
  • Steps to reproduce

Build docs developers (and LLMs) love