[GH-ISSUE #729] Admin plugin: admin.listUsers() returns 401 UNAUTHORIZED #17028

Closed
opened 2026-04-15 14:58:21 -05:00 by GiteaMirror · 2 comments
Owner

Originally created by @dpflucas on GitHub (Dec 2, 2024).
Original GitHub issue: https://github.com/better-auth/better-auth/issues/729

Describe the bug
When I try to run

const users = await authClient.admin.listUsers({
    query: {
      limit: 10,
      sortBy: 'createdAt',
      sortDirection: 'desc',
    },
  })

it returns

 GET /api/auth/admin/list-users?limit=10&sortBy=createdAt&sortDirection=desc 401 in 53ms
{
  data: null,
  error: { code: 'UNAUTHORIZED', status: 401, statusText: 'UNAUTHORIZED' }
}

However, for example when creating a User

const response = await authClient.admin.createUser({
          name: values.name,
          email: values.email,
          password: values.password,
          role: values.role,
        })

it works fine:

 POST /api/auth/admin/create-user?currentURL=http%3A%2F%2Flocalhost%3A3000%2Fadmin%2Fusers 200 in 1069ms

To Reproduce
Steps to reproduce the behavior:

  1. Enable admin plugin on Next.js
  2. Call authClient.admin.listUsers()
  3. Check the terminal
  4. See error on the terminal.

Expected behavior
It should return the list of Users.

Desktop (please complete the following information):

  • OS: macOS Sequoia 15.0
  • Browser: Chrome
  • Version: Version 131.0.6778.70 (Official Build) (arm64)

Additional context
If I try to run

const session = await auth.api.getSession({
    headers: await headers(),
  })

immediately before calling admin.listUsers, I can confirm the signed in user has the admin role:

console.log(session?.user.role)

> "admin"
Originally created by @dpflucas on GitHub (Dec 2, 2024). Original GitHub issue: https://github.com/better-auth/better-auth/issues/729 **Describe the bug** When I try to run ```ts const users = await authClient.admin.listUsers({ query: { limit: 10, sortBy: 'createdAt', sortDirection: 'desc', }, }) ``` it returns ``` GET /api/auth/admin/list-users?limit=10&sortBy=createdAt&sortDirection=desc 401 in 53ms { data: null, error: { code: 'UNAUTHORIZED', status: 401, statusText: 'UNAUTHORIZED' } } ``` However, for example when creating a User ```ts const response = await authClient.admin.createUser({ name: values.name, email: values.email, password: values.password, role: values.role, }) ``` it works fine: ``` POST /api/auth/admin/create-user?currentURL=http%3A%2F%2Flocalhost%3A3000%2Fadmin%2Fusers 200 in 1069ms ``` **To Reproduce** Steps to reproduce the behavior: 1. Enable admin plugin on Next.js 2. Call authClient.admin.listUsers() 3. Check the terminal 4. See error on the terminal. **Expected behavior** It should return the list of Users. **Desktop (please complete the following information):** - OS: macOS Sequoia 15.0 - Browser: Chrome - Version: Version 131.0.6778.70 (Official Build) (arm64) **Additional context** If I try to run ```ts const session = await auth.api.getSession({ headers: await headers(), }) ``` immediately before calling `admin.listUsers`, I can confirm the signed in user has the `admin` role: ```ts console.log(session?.user.role) > "admin" ```
GiteaMirror added the locked label 2026-04-15 14:58:21 -05:00
Author
Owner

@dpflucas commented on GitHub (Dec 3, 2024):

Update: I was able to make it work by adding the fetchOptions key with the Next.js headers

const response = await authClient.admin.listUsers({
    query: {
      limit: 10,
      sortBy: 'createdAt',
      sortDirection: 'desc',
      filterField: 'role',
      filterOperator: 'eq',
      filterValue: 'user',
    },
    fetchOptions: {
      headers: await headers(),
    },
  })

I assume this is because listUsers is being called on a server component, as described here ?

<!-- gh-comment-id:2514823478 --> @dpflucas commented on GitHub (Dec 3, 2024): Update: I was able to make it work by adding the `fetchOptions` key with the Next.js headers ```ts const response = await authClient.admin.listUsers({ query: { limit: 10, sortBy: 'createdAt', sortDirection: 'desc', filterField: 'role', filterOperator: 'eq', filterValue: 'user', }, fetchOptions: { headers: await headers(), }, }) ``` I assume this is because `listUsers` is being called on a server component, as described [here](https://www.better-auth.com/docs/integrations/next#rsc-and-server-actions) ?
Author
Owner

@abellaismail7 commented on GitHub (Feb 26, 2025):

I guest the API is updated and I don't know why the types aren't working properly fetchOptions doesn't exist anymore
Anyway here is the updated version

  const newUser = await auth.api.createUser({
    body: {
      name: `${data.firstName} ${data.lastName}`,
      email: data.email,
      role: data.role,
      password: password,
      data: {
        ///....
      },
    },
    headers: fromNodeHeaders(req.headers), // adjust based on your framework
  });
<!-- gh-comment-id:2686294233 --> @abellaismail7 commented on GitHub (Feb 26, 2025): I guest the API is updated and I don't know why the types aren't working properly fetchOptions doesn't exist anymore Anyway here is the updated version ```typescript const newUser = await auth.api.createUser({ body: { name: `${data.firstName} ${data.lastName}`, email: data.email, role: data.role, password: password, data: { ///.... }, }, headers: fromNodeHeaders(req.headers), // adjust based on your framework }); ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#17028