Problem: occasionally, our users will be unable to spawn a new singleuser for varying reasons. In general I would like to pass the errors that occur on the singleuserserver back to the hub spawner process to catch things like OSErorr when the users homedirectory is full and thus the server will fail to spawn
I judging from the documentation I’ve read from Spawners — JupyterHub documentation I was thinking that if I could populate Spawner.jupyterhub_message. The issue I’ve realized is that this is because the spawner forking a new process from c.Spawner.cmd , which where the exception actually gets raised.
2026-03-24 11:16:55.365 File “/opt/conda/lib/python3.12/site-packages/jupyter_server/serverapp.py”, line 2973, in write_browser_open_file
2026-03-24 11:16:55.365 with open(self.browser_open_file, "w", encoding="utf-8") as f:
2026-03-24 11:16:55.365 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-03-24 11:16:55.365 OSError: [Errno 122] Disk quota exceeded: ‘/home/user/.local/share/jupyter/runtime/jpserver-52-open.html’
So, my question is; how would I be able to get exceptions raised by the singleuser user to the spawn-pending page?
Possible Solutions:
1. Extend KubeSpawner to
I have tried this already and it seems like this won’t work due to the issue describe above with the spawner forking the singleuser process
```
hub.extraConfig:
KubeExtendedSpawner: |
from kubespawner import KubeSpawner
class KubeExtendedSpawner(KubeSpawner):
def start(self):
try:
self._start_future = asyncio.ensure_future(self._start())
return self._start_future
except Exception as e:
self.jupyterhub_message = e
raise RuntimeError(f"Server failed to start: {e}") from e
c.Jupyterhub.spawner_class = KubeExtendedSpawner
```
But perhaps I am just doing something wrong?
2. Surface Python exceptions from singleuser server to the pod events/containerStatus
I’m forgetting where I saw this in the config, but it seemed like for the spawner.poll it might be possible to get the container error from the the pod events/container status if we can surface the exception, and then add that to the spawner.jupyterhub_message or something like that?