Skip to content

getSessionCookie Returns null in Next.js 15.2 Edge Runtime #2170

Description

@camunoz2

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

  1. Set up a Next.js 15.2.1 project with better-auth version 1.2.3.​
  2. Implement the middleware.ts as follows:
import { NextRequest, NextResponse } from "next/server";
import { getSessionCookie } from "better-auth/cookies";

export function middleware(request: NextRequest) {
  const session = getSessionCookie(request, {
    cookieName: "session_token",
    cookiePrefix: "better-auth",
  });

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

  return NextResponse.next();
}

export const config = {
  matcher: ["/dashboard/:path*"],
};
  1. Ensure that the session cookie better-auth.session_token is set in the browser and sent with requests to /dashboard
  2. Access the /dashboard route

Current vs. Expected behavior

Expected Behavior: The middleware should detect the session cookie and allow access to the /dashboard route.​
Actual Behavior: The getSessionCookie function returns null, resulting in a redirect to the /unauthorized page.​

What version of Better Auth are you using?

1.2.3​

Provide environment information

- OS: Windows 11
- Browser Zen Browser (Firefox)

Which area(s) are affected? (Select all that apply)

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth";
import { admin } from "better-auth/plugins";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { db } from "@/lib/drizzle";
import { schema } from "@/db/schema/auth-schema";
import { nextCookies } from "better-auth/next-js";

export const auth = betterAuth({
  user: {
    additionalFields: {
      schoolId: {
        type: "number",
      },
    },
  },
  database: drizzleAdapter(db, {
    provider: "sqlite",
    schema: {
      ...schema,
    },
  }),
  plugins: [
    admin({
      requireRole: true,
      defaultRole: "unauthorized",
      adminRole: "admin",
      allowedRoles: ["admin", "user"],
      api: {
        enabled: true,
      },
    }),
    nextCookies(),
  ],
  socialProviders: {
    google: {
      clientId: process.env.GOOGLE_CLIENT_ID as string,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET as string,
    },
  },
});

export const { api } = auth;

export type Session = typeof auth.$Infer.Session;

Additional context

Logging request.cookies.getAll() within the middleware confirms the presence of the better-auth.session_token cookie.​

Manually retrieving the cookie using request.cookies.get("better-auth.session_token") works as expected, suggesting an issue with getSessionCookie in the Edge Runtime environment.​

The better-auth documentation indicates that getSessionCookie should function in middleware by matching the cookieName and cookiePrefix to the authentication configuration.​

Metadata

Metadata

Assignees

No one assigned

    Labels

    lockedLocked conversations after being closed for 7 days

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions