This line indicates that your custom LDAPAuthenticatorExtend
is not being taken into account. Check your JupyterHub config and ensure you are not overriding authenticator_class
somewhere else in the config
@mahendrapaipuri
Iām using below config
JupyterHub:
authenticator_class: ldapauthenticator.LDAPAuthenticator
No sure what is happening in your case. You can open a shell into hub container and check the contents of /usr/local/etc/jupyterhub/secret/values.yaml
to see if the extraConfig
is being taken into account or not.
I checked by logging into the hub pod and donāt find any extraConfig inside /usr/local/etc/jupyterhub/secret/values.yaml. So itās clearly pre_spawn_hook is not being called.
I was able to find the issue. I have a extraConfig: defined in values.yaml, which i forgot to delete it. Now the hook is being called, but getting below error.
[D 2025-07-08 19:10:10.535 JupyterHub base:1104] 0 active servers
[I 2025-07-08 19:10:10.568 JupyterHub provider:661] Creating oauth client jupyterhub-user-userid
[D 2025-07-08 19:10:10.590 JupyterHub <string>:6] running preSpawn hook
[D 2025-07-08 19:10:10.590 JupyterHub <string>:8] pre_spawn_start auth_state:<coroutine object User.get_auth_state at 0x7f4e4c21c040>
[E 2025-07-08 19:10:10.590 JupyterHub user:1007] Unhandled error starting userid's server: 'coroutine' object is not subscriptable
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/jupyterhub/user.py", line 894, in spawn
await maybe_future(authenticator.pre_spawn_start(self, spawner))
File "<string>", line 9, in pre_spawn_start
TypeError: 'coroutine' object is not subscriptable
My bad! get_auth_state
is coroutine, so we need to await
it. Modify the pre_spawn_start
as follows:
async def pre_spawn_start(self, user, spawner):
self.log.debug('running preSpawn hook')
auth_state = await spawner.user.get_auth_state()
if not auth_state:
return
self.log.debug('pre_spawn_start auth_state:%s' % auth_state)
spawner.environment["NB_UID"] = str(auth_state["uidNumber"][0])
spawner.environment["NB_GID"] = str(auth_state["gidNumber"][0])
spawner.environment["NB_USER"] = str(auth_state["uid"][0])
PS: I dont think the indentation is good in above snippet!! Format it properly before using!!
When i use the above code, i was able to login.But single user pod is spawning with default jovyan user
In the single user pod, do you see the env vars NB_UID
, NB_GID
and NB_USER
set? Do you see contents of auth_state
in hub logs?
My bad, i used @gen.coroutine. I removed it and iām getting error
Unhandled error starting user(which is user id i logged in)server: 'uidNumber'
Can you please share entire logs? What are there inside auth_state
?
pre_spawn_start auth_state:{'ldap_groups': [], 'user_attributes': {'gidNumber': [0000000], 'uidNumber': [1234567], 'uid': ['userid']}}
[E 2025-07-08 19:48:52.951 JupyterHub user:1007] Unhandled error starting userid's server: 'uidNumber'
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/jupyterhub/user.py", line 894, in spawn
await maybe_future(authenticator.pre_spawn_start(self, spawner))
File "<string>", line 11, in pre_spawn_start
KeyError: 'uidNumber'
[D 2025-07-08 19:48:52.951 JupyterHub user:1100] Stopping userid
[D 2025-07-08 19:48:52.960 JupyterHub user:1122] Deleting oauth client jupyterhub-user-userid
[D 2025-07-08 19:48:52.971 JupyterHub user:1125] Finished stopping userid
[W 2025-07-08 19:48:52.975 JupyterHub base:1194] 2 consecutive spawns failed. Hub will exit if failure count reaches 5 before succeeding
[E 2025-07-08 19:48:52.975 JupyterHub gen:629] Exception in Future <Task finished name='Task-34' coro=<BaseHandler.spawn_single_user.<locals>.finish_user_spawn() done, defined at /usr/local/lib/python3.12/site-packages/jupyterhub/handlers/base.py:1115> exception=KeyError('uidNumber')> after timeout
Traceback (most recent call last):
File "/usr/local/lib/python3.12/site-packages/tornado/gen.py", line 624, in error_callback
future.result()
File "/usr/local/lib/python3.12/site-packages/jupyterhub/handlers/base.py", line 1122, in finish_user_spawn
await spawn_future
File "/usr/local/lib/python3.12/site-packages/jupyterhub/user.py", line 1021, in spawn
raise e
File "/usr/local/lib/python3.12/site-packages/jupyterhub/user.py", line 894, in spawn
await maybe_future(authenticator.pre_spawn_start(self, spawner))
File "<string>", line 11, in pre_spawn_start
KeyError: 'uidNumber'
Well, it is clear from your auth_state
that your code should be spawner.environment["NB_UID"] = str(auth_state["user_attributes"]["uidNumber"][0])
.
Thanks @mahendrapaipuri . Now the pod is running with uid. Group id is pointing correctly, but referencing as uid.
uid=1234567(userid), gid=1000000(userid), groups=1000000(userid), 100(users)
it should run as
uid=1234567(userid), gid=1000000(ldapuser), groups=1000000(ldapuser), 100(users)
You will have to set NB_GROUP
env variable as well to get correct group name
I tried to set NB_GROUP as this format.
spawner.environment["NB_GROUP"] = str(auth_state["user_attributes"]["gidName"][0])
But my ldap doesnāt have the attribute gidName.
I set it manually and working as expected. But the files in /home/userid is created with root:root instead of userid:ldapuser
And also can i remove 100(users)
uid=1234567(userid), gid=1000000(ldapuser), groups=1000000(ldapuser), 100(users)