KitRocket

Auth Issues

Troubleshoot authentication problems — OAuth, sessions, magic links, and more.

OAuth callback URL mismatch

Symptom: After clicking "Sign in with Google/GitHub," you get a redirect error like "redirect_uri_mismatch."

Cause: The callback URL registered with the OAuth provider doesn't match what Better Auth generates.

Fix:

The callback URL format is:

{BETTER_AUTH_URL}/api/auth/callback/{provider}
  1. Check your BETTER_AUTH_URL:
# Development
BETTER_AUTH_URL="http://localhost:3000"

# Production
BETTER_AUTH_URL="https://yourdomain.com"
  1. Update the callback URL in each provider:

Google Cloud Console:

http://localhost:3000/api/auth/callback/google
https://yourdomain.com/api/auth/callback/google

GitHub Developer Settings:

http://localhost:3000/api/auth/callback/github
https://yourdomain.com/api/auth/callback/github
  1. Make sure there are no trailing slashes — /callback/google not /callback/google/

AUTH_SECRET not set

Symptom: App crashes with AUTH_SECRET is not set or sessions don't work.

Cause: The AUTH_SECRET environment variable is missing or empty.

Fix:

Generate a secure secret:

openssl rand -base64 32

Add it to .env.local:

AUTH_SECRET="your-generated-secret-here"

Important: use a different secret for each environment (development, staging, production). If you change the secret, all existing sessions become invalid.

Session not persisting after login

Symptom: You log in successfully but are immediately logged out, or refreshing the page loses the session.

Cause: Cookie configuration issues.

Fix:

  1. Check your URL: Make sure you're accessing the app at http://localhost:3000, not http://127.0.0.1:3000. Cookies are domain-specific.

  2. Check BETTER_AUTH_URL: This must match the URL you're accessing:

BETTER_AUTH_URL="http://localhost:3000"
  1. Clear cookies: Open DevTools > Application > Cookies, clear all cookies for localhost, and try again.

  2. Check for HTTPS issues: In production, cookies require HTTPS. Make sure your domain has SSL configured (Vercel does this automatically).

  3. Check session expiration: If sessions expire too quickly, increase the duration:

export const auth = betterAuth({
  session: {
    expiresIn: 60 * 60 * 24 * 30, // 30 days
  },
});

Symptom: User requests a magic link but never receives the email.

Cause: Email service not configured, domain not verified, or email going to spam.

Fix:

  1. Check Resend is configured:
RESEND_API_KEY="re_your-api-key"
EMAIL_FROM="noreply@yourdomain.com"
  1. Check the Resend dashboard: Go to resend.com/emails and look for the email in the logs. You'll see if it was sent, delivered, or bounced.

  2. Check spam/junk folder: Magic link emails sometimes get flagged, especially with unverified domains.

  3. Verify your domain: In Resend dashboard > Domains, make sure your sending domain is verified. Without verification, emails may not deliver or go to spam.

  4. Check the server logs: Look for error messages from the email sending function.

"Invalid credentials" on login

Symptom: Login fails with "Invalid credentials" even with the correct email.

Cause: Wrong password, or the account was created with OAuth (no password set).

Fix:

  1. If the user registered with Google/GitHub, they don't have a password. They need to use the same OAuth provider to log in.

  2. Check the accounts table in your database to see which providers are linked:

SELECT provider FROM accounts WHERE user_id = 'the-user-id';
  1. If the user wants to set a password, implement a "Set Password" flow in the settings page.

Google OAuth "Access blocked" error

Symptom: Google shows "Access blocked: This app's request is invalid" or "Error 403: access_denied."

Cause: OAuth consent screen not configured or app needs verification.

Fix:

  1. Go to Google Cloud Console
  2. Configure the OAuth consent screen:
    • App name, support email, developer contact
    • Add your domain to "Authorized domains"
  3. For development, set the app to "Testing" and add your email as a test user
  4. For production with 100+ users, submit for Google verification

GitHub OAuth "Application suspended" error

Symptom: GitHub shows "Application suspended" when trying to log in.

Cause: The GitHub OAuth app was suspended, or the client credentials are wrong.

Fix:

  1. Go to GitHub Developer Settings > OAuth Apps
  2. Verify the app exists and is not suspended
  3. Regenerate the client secret if needed
  4. Update GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET in .env.local

CORS errors on auth endpoints

Symptom: Browser console shows Access-Control-Allow-Origin errors when making auth requests.

Cause: Frontend making requests to a different origin than the auth server.

Fix:

  1. Make sure BETTER_AUTH_URL matches the URL your frontend uses
  2. If your frontend and API are on different domains, configure CORS in Better Auth:
export const auth = betterAuth({
  trustedOrigins: [
    "http://localhost:3000",
    "https://yourdomain.com",
  ],
});
  1. In most KitRocket setups, frontend and API are on the same origin, so CORS isn't needed.

Users can access dashboard without logging in

Symptom: Protected pages are accessible without authentication.

Cause: Auth middleware not running or not configured correctly.

Fix:

  1. Check that middleware exists and covers the right paths:
export { authMiddleware as default } from "@/lib/auth/middleware";

export const config = {
  matcher: ["/dashboard/:path*", "/settings/:path*", "/billing/:path*"],
};
  1. Verify the middleware checks the session:
export async function authMiddleware(request: NextRequest) {
  const session = await auth.api.getSession({
    headers: request.headers,
  });

  if (!session) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  return NextResponse.next();
}
  1. Clear your browser cookies and test in an incognito window to rule out cached sessions.

On this page