Better Auth returns NOT_FOUND for all routes in Express API #1338

Closed
opened 2026-03-13 08:33:52 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @ohabash on GitHub (Jun 11, 2025).

Better Auth returns NOT_FOUND for all routes in Express API

Environment

  • Better Auth version: "better-auth": "^1.2.8",
  • Express version: "express": "^4.21.2",
  • Node.js version: v20.9.0
  • Database: MongoDB with mongodbAdapter also tried with prisma no difference

Setup

// auth.ts
const ops: BetterAuthOptions = {
  database: mongodbAdapter(mongoService.client.db()),
  emailAndPassword: { enabled: true },
  basePath: '/api/v1/auth',
  appName: 'company',
  plugins: [organization(), admin(), apiKey(), jwt()],
  // ... other config
};

export function initAuth() {
  if (!auth) {
    auth = betterAuth(ops);
  }
  return auth;
}
// Express middleware
const auth = initAuth();
app.use('/api/v1/auth', (req, res, next) => {
  req.url = `/api/v1/auth${req.url}`;

  toNodeHandler(auth)(req, res)
    .then(() => {
      console.log(`🔍 what did toNodeHandler do: ${req.method} ${req.originalUrl}`);
      next();
    })
    .catch(err => {
      console.error('Auth API Error:', err);
      res.status(500).json({ error: 'Authentication service error' });
    });
});

Issue

All Better Auth endpoints return NOT_FOUND:

GET /api/v1/auth/ok
POST /api/v1/auth/sign-up
POST /api/v1/auth/sign-in

Logs show middleware is executing:

🔍 what did toNodeHandler do: GET /api/v1/auth/ok
🔍 next Middleware: GET /api/v1/auth/ok

What I've Tried

  • Multiple middleware variations
  • Verified auth initializes successfully
  • Confirmed basePath matches route
  • URL manipulation in middleware

Question

my request passed right through the toNodeHandler no error no success.
How do I properly integrate Better Auth with Express? The middleware runs but Better Auth doesn't recognize any routes

Originally created by @ohabash on GitHub (Jun 11, 2025). # Better Auth returns NOT_FOUND for all routes in Express API ## Environment - **Better Auth version**: `"better-auth": "^1.2.8",` - **Express version**: `"express": "^4.21.2",` - **Node.js version**: ` v20.9.0 ` - **Database**: MongoDB with mongodbAdapter also tried with prisma no difference ## Setup ```typescript // auth.ts const ops: BetterAuthOptions = { database: mongodbAdapter(mongoService.client.db()), emailAndPassword: { enabled: true }, basePath: '/api/v1/auth', appName: 'company', plugins: [organization(), admin(), apiKey(), jwt()], // ... other config }; export function initAuth() { if (!auth) { auth = betterAuth(ops); } return auth; } ``` ```typescript // Express middleware const auth = initAuth(); app.use('/api/v1/auth', (req, res, next) => { req.url = `/api/v1/auth${req.url}`; toNodeHandler(auth)(req, res) .then(() => { console.log(`🔍 what did toNodeHandler do: ${req.method} ${req.originalUrl}`); next(); }) .catch(err => { console.error('Auth API Error:', err); res.status(500).json({ error: 'Authentication service error' }); }); }); ``` ## Issue All Better Auth endpoints return `NOT_FOUND`: ``` GET /api/v1/auth/ok POST /api/v1/auth/sign-up POST /api/v1/auth/sign-in ``` Logs show middleware is executing: ``` 🔍 what did toNodeHandler do: GET /api/v1/auth/ok 🔍 next Middleware: GET /api/v1/auth/ok ``` ## What I've Tried - Multiple middleware variations - Verified auth initializes successfully - Confirmed basePath matches route - URL manipulation in middleware ## Question my request passed right through the `toNodeHandler` no error no success. How do I properly integrate Better Auth with Express? The middleware runs but Better Auth doesn't recognize any routes
GiteaMirror added the expressquestion labels 2026-03-13 08:33:52 -05:00
Author
Owner

@dosubot[bot] commented on GitHub (Jun 11, 2025):

Your issue is likely due to how the Better Auth handler is mounted in Express. For Express v4, you should use a catch-all route like this:

app.all('/api/v1/auth/*', toNodeHandler(auth));

Avoid using express.json() before the Better Auth handler, as it can interfere with request processing and cause endpoints to hang or return NOT_FOUND responses. Also, make sure you are using the correct config key: it should be baseURL (not baseUrl) in your Better Auth options—using the wrong key can break route recognition docs.

You do not need to manipulate req.url in your middleware; just mount the handler directly as above. If you are on Express v5, use the new catch-all syntax: app.all('/api/v1/auth/{*any}', toNodeHandler(auth)); docs.

If you still get NOT_FOUND, double-check that your basePath in Better Auth options matches the route you mount in Express, and that you are not using any disabled paths or plugins that might block these endpoints.

Written by @dosu, approved by Bekacru

To reply, just mention @dosu.


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

@dosubot[bot] commented on GitHub (Jun 11, 2025): <!-- Answer --> Your issue is likely due to how the Better Auth handler is mounted in Express. For Express v4, you should use a catch-all route like this: ```js app.all('/api/v1/auth/*', toNodeHandler(auth)); ``` Avoid using `express.json()` before the Better Auth handler, as it can interfere with request processing and cause endpoints to hang or return NOT_FOUND responses. Also, make sure you are using the correct config key: it should be `baseURL` (not `baseUrl`) in your Better Auth options—using the wrong key can break route recognition [docs](https://github.com/better-auth/better-auth/blob/a47b9523e4c14ac18521cff8b087f1140273f528/docs/content/docs/integrations/express.mdx). You do not need to manipulate `req.url` in your middleware; just mount the handler directly as above. If you are on Express v5, use the new catch-all syntax: `app.all('/api/v1/auth/{*any}', toNodeHandler(auth));` [docs](https://github.com/better-auth/better-auth/blob/a47b9523e4c14ac18521cff8b087f1140273f528/docs/content/docs/installation.mdx). If you still get NOT_FOUND, double-check that your `basePath` in Better Auth options matches the route you mount in Express, and that you are not using any disabled paths or plugins that might block these endpoints. _Written by @dosu, approved by Bekacru_ <!-- 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/accc0224-a6d1-484e-82c4-df0118268813?feedback_type=great_response) | [Irrelevant](https://app.dosu.dev/response-feedback/accc0224-a6d1-484e-82c4-df0118268813?feedback_type=irrelevant_answer) | [Incorrect](https://app.dosu.dev/response-feedback/accc0224-a6d1-484e-82c4-df0118268813?feedback_type=incorrect_sources) | [Verbose](https://app.dosu.dev/response-feedback/accc0224-a6d1-484e-82c4-df0118268813?feedback_type=too_verbose) | [Hallucination](https://app.dosu.dev/response-feedback/accc0224-a6d1-484e-82c4-df0118268813?feedback_type=hallucination) | [Report 🐛](https://app.dosu.dev/response-feedback/accc0224-a6d1-484e-82c4-df0118268813?feedback_type=bug_report) | [Other](https://app.dosu.dev/response-feedback/accc0224-a6d1-484e-82c4-df0118268813?feedback_type=other)</sup>&nbsp;&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/2975)
Author
Owner

@ohabash commented on GitHub (Jun 11, 2025):

Your issue is likely due to how the Better Auth handler is mounted in Express. For Express v4, you should use a catch-all route like this:

app.all('/api/v1/auth/*', toNodeHandler(auth));
Avoid using express.json() before the Better Auth handler, as it can interfere with request processing and cause endpoints to hang or return NOT_FOUND responses. Also, make sure you are using the correct config key: it should be baseURL (not baseUrl) in your Better Auth options—using the wrong key can break route recognition docs.

My config was simply missing baseURL ... Thank you

Although the things you said about express routing dont apply in my project. You should consider putting app.use in the docs (express <5)

Thank you again.

@ohabash commented on GitHub (Jun 11, 2025): > Your issue is likely due to how the Better Auth handler is mounted in Express. For Express v4, you should use a catch-all route like this: > > app.all('/api/v1/auth/*', toNodeHandler(auth)); > Avoid using `express.json()` before the Better Auth handler, as it can interfere with request processing and cause endpoints to hang or return NOT_FOUND responses. Also, make sure you are using the correct config key: it should be `baseURL` (not `baseUrl`) in your Better Auth options—using the wrong key can break route recognition [docs](https://github.com/better-auth/better-auth/blob/a47b9523e4c14ac18521cff8b087f1140273f528/docs/content/docs/integrations/express.mdx). > My config was simply missing `baseURL` ... Thank you Although the things you said about express routing dont apply in my project. You should consider putting `app.use` in the docs (express <5) Thank you again.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#1338