API token does not allow me to delete users

I created an API token via <hub_url>/hub/token as an admin user.
This token allows me to fetch the list of users but whenever I try to use it to remove users or stop servers, I get a 403 error and the hub log says:

403 DELETE /exam/api/users/potato1 (10.20.165.10): '_xsrf' argument missing from DELETE
[I 2025-01-14 14:42:22.346 JupyterHub _xsrf_utils:125] Setting new xsrf cookie for b'None:ZuQiOEtUD_gaEf5x3POF1XTsm5yrO8RPGtMWUy1e9Bw=' {'path': '/exam/hub/', 'max_age': 3600}
[D 2025-01-14 14:42:22.347 JupyterHub base:1471] No template for 403
[W 2025-01-14 14:42:22.350 JupyterHub log:192] 403 DELETE /exam/api/users/potato1 (@10.20.165.10) 3.92ms

My code to make the request (where token is the correct token generated) is:

requests.delete(
    url=f"{hub_url}/api/users/potato1",
    headers=dict(
        Authorization=f"token {token}",
    ),
    verify=False, # Self signed ssl certificate
)

Using curl I get the same error.

I am using z2jh, with helm-chart version 3.3.8 and JupyterHub 4.1.6. The user and auth part of the values.yaml looks like this:

hub:
  config:
    JupyterHub:
      authenticator_class: firstuseauthenticator.FirstUseAuthenticator
    Authenticator:
      allowed_users:
          - tmetzl
      admin_users:
          - tmetzl

What am I doing wrong and what could be the cause of this?

Looks like the URL might be missing a /hub/. It should be {hub_url}/hub/api/users/{username}, not {hub_url}/api/users/{username}. GET requests work because there is a default redirect if /hub/ is missing, but this only works for GET requests. DELETE doesn’t follow redirects. The error is weird, though! It should be a 404, which would be more informative.

For the successful requests, do you see logs with 302, like:

[I 2025-01-15 13:14:26.857 JupyterHub log:192] 302 GET /api/users/test → /hub/api/users/test-3 (@::ffff:127.0.0.1) 0.75ms
[I 2025-01-15 13:14:26.872 JupyterHub log:192] 200 GET /hub/api/users/test (admin@::ffff:127.0.0.1) 7.63ms

Thank you, I was indeed missing the /hub and the get requests were redirected.