HTTP 500 error in Docker Jupyterhub when requesting user tokens

Hoi there,

I’m trying to create tokens (non API) for a number of auto-created users. Here’s what I’m doing:

  1. Create Docker image of a Jupyterhub with a custom configure file that has an admin user and API token (works)
  2. Start the Docker image as a container (works)
  3. Test the REST API with the admin token to see if I have access (works)
  4. Use the REST API with the admin token to create users (works)
  5. Use the REST API to create tokens for each created user using the same admin user and token (fails)

The POST url I’m using is (fictitious username):

http://localhost:10000/hub/api/users/cstuart/tokens

With JSON body taken directly from the API documentation:

{
   "expires_in": 0,
   "note":"Automatically generated auth token",
   "roles":[
      "user"
   ]
}

In the console where I run the custom container I see the following.

[I 2023-04-07 17:34:10.708 JupyterHub users:421] Service admin requested API token for cstuart
[E 2023-04-07 17:34:10.709 JupyterHub web:1798] Uncaught exception POST /hub/api/users/cstuart/tokens (::ffff:172.17.0.1)
    HTTPServerRequest(protocol='http', host='localhost:10000', method='POST', uri='/hub/api/users/cstuart/tokens', version='HTTP/1.1', remote_ip='::ffff:172.17.0.1')
    Traceback (most recent call last):
      File "/usr/local/lib/python3.10/dist-packages/tornado/web.py", line 1713, in _execute
        result = await result
      File "/usr/local/lib/python3.10/dist-packages/jupyterhub/apihandlers/users.py", line 431, in post
        token_model = self.token_model(orm.APIToken.find(self.db, api_token))
      File "/usr/local/lib/python3.10/dist-packages/jupyterhub/apihandlers/base.py", line 233, in token_model
        if token.user:
    AttributeError: 'NoneType' object has no attribute 'user'
    
[E 2023-04-07 17:34:10.709 JupyterHub log:178] {
      "X-Forwarded-Host": "localhost:10000",
      "X-Forwarded-Proto": "http",
      "X-Forwarded-Port": "10000",
      "X-Forwarded-For": "::ffff:172.17.0.1",
      "Content-Length": "109",
      "Connection": "close",
      "Accept-Encoding": "gzip, deflate, br",
      "Host": "localhost:10000",
      "Postman-Token": "1f0a63d6-c1bf-4b91-88e0-e7c862620495",
      "Accept": "*/*",
      "User-Agent": "PostmanRuntime/7.29.2",
      "Content-Type": "application/json",
      "Authorization": "token [secret]"
    }
[E 2023-04-07 17:34:10.709 JupyterHub log:186] 500 POST /hub/api/users/cstuart/tokens (admin@::ffff:172.17.0.1) 8.44ms
2 Likes

I am facing the same problem, have you resolved it?

Hoi there,

I never found out why the server didn’t take the JSON data as officially specified. The only workaround I found was to supply {} instead of the data block shown in the documentation. When I do that I get the expected JSON back including a newly generated token.

1 Like

It really works,thanks.

Short answer: 0 is not a valid expires_in: use null or a positive integer.

The REST API docs should specify, but to have no expiration, omit expires_in, or specify expires_in: null. Specifying 0 is telling JupyterHUb to create a token that will expire immediately, which means the internal retrieval after creating the token fails because the token is deleted as soon as it is created.

Fixed by Improve validation, docs for token.expires_in by minrk · Pull Request #4677 · jupyterhub/jupyterhub · GitHub, which is mostly a docs/error-reporting improvement, but also accepts 0 as meaning no expiration.