No response is returned from route handler when getting session with x-api-key #1939

Closed
opened 2026-03-13 09:13:51 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @KingDoxik on GitHub (Sep 16, 2025).

Originally assigned to: @himself65 on GitHub.

Is this suited for github?

  • Yes, this is suited for github

To Reproduce

Setup better-auth in Nextjs.
Setup better-auth client in pure Nodejs CLI app with vanilla client.
Create API key
Call getSession from client and pass x-api-key as a header

Current vs. Expected behavior

Currently it fails on the API with messge No response is returned from route handler '/auth/[...all]/route.ts'. Ensure you return a Response or a NextResponse in all branches of your handler.]
GET /api/auth/get-session 500 in 1175ms. Better-auth is working properly in other cases like signup, sign-in, api key creation.

What version of Better Auth are you using?

1.3.11

System info

{
  "system": {
    "platform": "darwin",
    "arch": "arm64",
    "version": "Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:51 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T8112",
    "release": "24.6.0",
    "cpuCount": 8,
    "cpuModel": "Apple M2",
    "totalMemory": "16.00 GB",
    "freeMemory": "0.30 GB"
  },
  "node": {
    "version": "v22.16.0",
    "env": "development"
  },
  "packageManager": {
    "name": "pnpm",
    "version": "10.7.1"
  },
  "frameworks": null,
  "databases": null,
  "betterAuth": {
    "version": "^1.3.11",
    "config": null
  }
}

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

Backend

Auth config (if applicable)

import { betterAuth } from "better-auth"

// NextJS API
const createBetterAuth = (db: Database) =>
  betterAuth({
    baseURL: APP_DOMAIN,
    database: drizzleAdapter(db, {
      provider: 'mysql',
      schema
    }),
    socialProviders: {
      github: {
        clientId: process.env.GITHUB_CLIENT_ID as string,
        clientSecret: process.env.GITHUB_CLIENT_SECRET as string
      }
    },
    emailAndPassword: {
      enabled: true
    },
    plugins: [
      organization(),
      apiKey({
        rateLimit: {
          enabled: false
        }
      }),
      nextCookies()
    ]
  });

export const auth = createBetterAuth(db);

// Node js CLI
const authClient: ReturnType<typeof createAuthClient> = createAuthClient({
  baseURL: process.env.API_URL,
  plugins: [apiKeyClient()]
});

const session = await client.getSession({
  fetchOptions: {
    headers: {
      'x-api-key': apiKey
    }
  }
});

Additional context

I feel like it is similar to https://github.com/better-auth/better-auth/issues/3588. In my case I am calling the client from CLI, fully separate from the Nextjs API.

Originally created by @KingDoxik on GitHub (Sep 16, 2025). Originally assigned to: @himself65 on GitHub. ### Is this suited for github? - [x] Yes, this is suited for github ### To Reproduce Setup better-auth in Nextjs. Setup better-auth client in pure Nodejs CLI app with vanilla client. Create API key Call getSession from client and pass x-api-key as a header ### Current vs. Expected behavior Currently it fails on the API with messge No response is returned from route handler '/auth/[...all]/route.ts'. Ensure you return a `Response` or a `NextResponse` in all branches of your handler.] GET /api/auth/get-session 500 in 1175ms. Better-auth is working properly in other cases like signup, sign-in, api key creation. ### What version of Better Auth are you using? 1.3.11 ### System info ```bash { "system": { "platform": "darwin", "arch": "arm64", "version": "Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:51 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T8112", "release": "24.6.0", "cpuCount": 8, "cpuModel": "Apple M2", "totalMemory": "16.00 GB", "freeMemory": "0.30 GB" }, "node": { "version": "v22.16.0", "env": "development" }, "packageManager": { "name": "pnpm", "version": "10.7.1" }, "frameworks": null, "databases": null, "betterAuth": { "version": "^1.3.11", "config": null } } ``` ### Which area(s) are affected? (Select all that apply) Backend ### Auth config (if applicable) ```typescript import { betterAuth } from "better-auth" // NextJS API const createBetterAuth = (db: Database) => betterAuth({ baseURL: APP_DOMAIN, database: drizzleAdapter(db, { provider: 'mysql', schema }), socialProviders: { github: { clientId: process.env.GITHUB_CLIENT_ID as string, clientSecret: process.env.GITHUB_CLIENT_SECRET as string } }, emailAndPassword: { enabled: true }, plugins: [ organization(), apiKey({ rateLimit: { enabled: false } }), nextCookies() ] }); export const auth = createBetterAuth(db); // Node js CLI const authClient: ReturnType<typeof createAuthClient> = createAuthClient({ baseURL: process.env.API_URL, plugins: [apiKeyClient()] }); const session = await client.getSession({ fetchOptions: { headers: { 'x-api-key': apiKey } } }); ``` ### Additional context I feel like it is similar to https://github.com/better-auth/better-auth/issues/3588. In my case I am calling the client from CLI, fully separate from the Nextjs API.
GiteaMirror added the nextjsbug labels 2026-03-13 09:13:51 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Sep 16, 2025):

Hi @KingDoxik! I'm Dosu and I’m helping the better-auth team.

This is a known issue and is directly related to issue #3588: using authClient.getSession in a Next.js API route will cause the error about no response being returned. The correct approach is to use auth.api.getSession in your API route handler, not authClient.getSession—the latter is only for client-side use.

When handling API key authentication, Better Auth expects all code paths (including error cases like invalid or missing API key) to return a Response or NextResponse. If any branch fails to do so, you'll get a 500 error with the message you described. The API key plugin extracts and validates the key, and if valid, sets the session in context and returns it for /get-session requests; if invalid, it throws an error that must be handled by returning a response in your route handler (source).

Recent updates ensure the getSession route always returns a response via ctx.json() (source). If you're on v1.3.11 and still seeing this, double-check that your handler uses auth.api.getSession and that all error branches return a response.

For CLI clients, just send the x-api-key header; Better Auth will handle verification and session retrieval automatically (source). If you need the full response (including headers), use the asResponse option with getSession.

If you proxy requests or use a remote auth server, make sure to forward all headers and cookies and always construct a new Response from the remote server's response (source).

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Sep 16, 2025): <!-- Greeting --> Hi @KingDoxik! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the better-auth team. <!-- Answer --> This is a known issue and is directly related to [issue #3588](https://github.com/better-auth/better-auth/issues/3588): using `authClient.getSession` in a Next.js API route will cause the error about no response being returned. The correct approach is to use `auth.api.getSession` in your API route handler, not `authClient.getSession`—the latter is only for client-side use. When handling API key authentication, Better Auth expects all code paths (including error cases like invalid or missing API key) to return a `Response` or `NextResponse`. If any branch fails to do so, you'll get a 500 error with the message you described. The API key plugin extracts and validates the key, and if valid, sets the session in context and returns it for `/get-session` requests; if invalid, it throws an error that must be handled by returning a response in your route handler ([source](https://github.com/better-auth/better-auth/blob/4df178463eeeced7972c9a59f902b4bbf55db30b/packages/better-auth/src/plugins/api-key/index.ts)). Recent updates ensure the getSession route always returns a response via `ctx.json()` ([source](https://github.com/better-auth/better-auth/pull/4558)). If you're on v1.3.11 and still seeing this, double-check that your handler uses `auth.api.getSession` and that all error branches return a response. For CLI clients, just send the `x-api-key` header; Better Auth will handle verification and session retrieval automatically ([source](https://github.com/better-auth/better-auth/issues/4023)). If you need the full response (including headers), use the `asResponse` option with `getSession`. If you proxy requests or use a remote auth server, make sure to forward all headers and cookies and always construct a new `Response` from the remote server's response ([source](https://github.com/better-auth/better-auth/issues/4044)). <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/45b46fe9-51ca-4b63-9aa6-3bdbda34c384?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/45b46fe9-51ca-4b63-9aa6-3bdbda34c384?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/45b46fe9-51ca-4b63-9aa6-3bdbda34c384?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/45b46fe9-51ca-4b63-9aa6-3bdbda34c384?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/45b46fe9-51ca-4b63-9aa6-3bdbda34c384?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/45b46fe9-51ca-4b63-9aa6-3bdbda34c384?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/45b46fe9-51ca-4b63-9aa6-3bdbda34c384?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/4698)
Author
Owner

@KingDoxik commented on GitHub (Sep 16, 2025):

@dosubot No, I am not calling it server side like in the issue mentioned. I am calling getSession from a client (that is a NodeJS CLI app)

@KingDoxik commented on GitHub (Sep 16, 2025): @dosubot No, I am not calling it server side like in the issue mentioned. I am calling getSession from a client (that is a NodeJS CLI app)
Author
Owner

@dosubot[bot] commented on GitHub (Sep 16, 2025):

This is a known bug in Better Auth's API Key plugin: when you call getSession from a CLI client using x-api-key, the plugin may intercept the request and return a plain session object instead of a proper Response, which breaks Next.js route handling and causes the 500 error you see. This isn't a misconfiguration—it's an internal issue with the plugin's middleware short-circuiting the route handler [details].

There isn't an official fix yet, but you can work around it by manually wrapping the returned session object in a Response in your API route or proxy handler. For example:

// In your Next.js API route handler
const session = await auth.api.getSession({ headers: request.headers });
return new Response(JSON.stringify(session), { status: 200, headers: { 'content-type': 'application/json' } });

Make sure all error branches also return a Response. If you're proxying requests, always construct a new Response from the backend's response [example].

Keep an eye on upstream updates for a permanent fix. Let me know if you need help with the workaround code!

To reply, just mention @dosu.


How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other  Chat with Dosu Join Discord Share on X

@dosubot[bot] commented on GitHub (Sep 16, 2025): <!-- Answer --> This is a known bug in Better Auth's API Key plugin: when you call getSession from a CLI client using x-api-key, the plugin may intercept the request and return a plain session object instead of a proper Response, which breaks Next.js route handling and causes the 500 error you see. This isn't a misconfiguration—it's an internal issue with the plugin's middleware short-circuiting the route handler [[details](https://github.com/better-auth/better-auth/issues/4412)]. There isn't an official fix yet, but you can work around it by manually wrapping the returned session object in a Response in your API route or proxy handler. For example: ```ts // In your Next.js API route handler const session = await auth.api.getSession({ headers: request.headers }); return new Response(JSON.stringify(session), { status: 200, headers: { 'content-type': 'application/json' } }); ``` Make sure all error branches also return a Response. If you're proxying requests, always construct a new Response from the backend's response [[example](https://github.com/better-auth/better-auth/issues/4044)]. Keep an eye on upstream updates for a permanent fix. Let me know if you need help with the workaround code! <!-- Dosu Comment Footer --> *To reply, just mention [@dosu](https://go.dosu.dev/dosubot).* --- <sup>How did I do? [Good](https://app.dosu.dev/response-feedback/084df4cf-be6f-4cfb-b32c-957e04b54f39?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/084df4cf-be6f-4cfb-b32c-957e04b54f39?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/084df4cf-be6f-4cfb-b32c-957e04b54f39?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/084df4cf-be6f-4cfb-b32c-957e04b54f39?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/084df4cf-be6f-4cfb-b32c-957e04b54f39?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/084df4cf-be6f-4cfb-b32c-957e04b54f39?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/084df4cf-be6f-4cfb-b32c-957e04b54f39?feedback_type=other)</sup>&nbsp;&nbsp;[![Chat with Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/cdda13d9-dd27-4d31-b09a-5d8bec92de21/ask?utm_source=github)&nbsp;[![Join Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoColor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/better-auth/better-auth/issues/4698)
Author
Owner

@CarrettaRiccardo commented on GitHub (Sep 24, 2025):

Same issue here, retrieving api key header (or hard-coded) from server side always returns null session.

/api/test/route.ts

export async function GET(request: NextRequest) {
    const session = await auth.api.getSession({
      headers: new Headers({
        [API_KEY_HEADER]: "pk_key",
      }),
    });

    // tested dosubot answer, and also "asResponse: true"
    // return new Response(JSON.stringify(session), { status: 200, headers: { 'content-type': 'application/json' } });

    return NextResponse.json<ActionResponse>({ success: true, payload: session });
}
@CarrettaRiccardo commented on GitHub (Sep 24, 2025): Same issue here, retrieving api key header (or hard-coded) from server side always returns `null` session. `/api/test/route.ts` ```ts export async function GET(request: NextRequest) { const session = await auth.api.getSession({ headers: new Headers({ [API_KEY_HEADER]: "pk_key", }), }); // tested dosubot answer, and also "asResponse: true" // return new Response(JSON.stringify(session), { status: 200, headers: { 'content-type': 'application/json' } }); return NextResponse.json<ActionResponse>({ success: true, payload: session }); } ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1939