User subdomains: OAuth state missing

I am trying to enable user subdomains on a jupyterhub deployment with helm chart version 3.8.3.

hub:config: 
      AzureAdOAuthenticator:
        allow_all: true
        username: unique_name
        oauth_callback_url: https://jupyterhub.test.run/hub/oauth_callback
        enable_auth_state: true
      JupyterHub:
        authenticator_class: azuread
        hub_connect_url: "http://hub.jupyterhub.svc.cluster.local:8081"    
proxy:                                                                                              
     traefik:                                                                                                   
          hsts:
             includeSubdomains: true                                                                  
     https:
          enabled: true
          hosts:
            - '*.jupyterhub.test.run'
            - 'jupyterhub.test.run'

with c.JupyterHub.subdomain_host = “https://jupyterhub.test.run
as extraConfig on hub

now when I login it changes the domain to the correct one including the username and redirects me again to the login. After the relogin it throws:

                              # 400 : Bad Request
                              
                              OAuth state missing from cookies 

Any of you has any idea what setting I am missing?

Can you turn on debug logging and show us your full logs?

these are the logs from hub pod:

[D 2024-10-18 15:19:35.556 JupyterHub scopes:884] Checking access to /hub/spawn/test%20user via scope servers
[D 2024-10-18 15:19:35.556 JupyterHub scopes:697] Argument-based access to /hub/spawn/test%20user via servers
[D 2024-10-18 15:19:35.558 JupyterHub pages:218] Triggering spawn with default options for test user
[D 2024-10-18 15:19:35.558 JupyterHub base:407] Refreshing auth for test user
[D 2024-10-18 15:19:35.559 JupyterHub base:1061] Initiating spawn for test user
[D 2024-10-18 15:19:35.559 JupyterHub base:1065] 0/64 concurrent spawns
[D 2024-10-18 15:19:35.559 JupyterHub base:1070] 0 active servers
[I 2024-10-18 15:19:35.632 JupyterHub provider:660] Creating oauth client jupyterhub-user-test%20user
[I 2024-10-18 15:19:35.664 JupyterHub log:192] 302 GET /hub/spawn/test%20user -> /hub/spawn-pending/test%20user (test user@::ffff:100.64.0.1) 121.39ms
[D 2024-10-18 15:19:35.682 JupyterHub user:797] Calling Spawner.start for test user
[I 2024-10-18 15:19:35.714 JupyterHub reflector:282] watching for pods with label selector='component=singleuser-server' in namespace jupyterhub
[D 2024-10-18 15:19:35.715 JupyterHub reflector:289] Connecting pods watcher
[I 2024-10-18 15:19:35.718 JupyterHub reflector:282] watching for events with field selector='involvedObject.kind=Pod' in namespace jupyterhub
[D 2024-10-18 15:19:35.719 JupyterHub reflector:289] Connecting events watcher
[I 2024-10-18 15:19:35.722 JupyterHub spawner:2551] Attempting to create pvc claim-test-20user, with timeout 3
[D 2024-10-18 15:19:35.752 JupyterHub scopes:884] Checking access to /hub/spawn-pending/test%20user via scope servers
[D 2024-10-18 15:19:35.752 JupyterHub scopes:697] Argument-based access to /hub/spawn-pending/test%20user via servers
[I 2024-10-18 15:19:35.754 JupyterHub pages:399] test user is pending spawn
[I 2024-10-18 15:19:35.759 JupyterHub log:192] 200 GET /hub/spawn-pending/test%20user (test user@::ffff:100.64.0.1) 20.97ms
[I 2024-10-18 15:19:35.759 JupyterHub spawner:2567] PVC claim-test-20user already exists, so did not create new pvc.
[I 2024-10-18 15:19:35.763 JupyterHub spawner:2511] Attempting to create pod jupyter-test-20user, with timeout 3
[D 2024-10-18 15:19:35.954 JupyterHub scopes:884] Checking access to /hub/api/users/test%20user/server/progress via scope read:servers
[D 2024-10-18 15:19:35.954 JupyterHub scopes:697] Argument-based access to /hub/api/users/test%20user/server/progress via read:servers
[D 2024-10-18 15:19:35.959 JupyterHub spawner:2303] progress generator: jupyter-test-20user
[D 2024-10-18 15:19:36.486 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.61ms
[D 2024-10-18 15:19:38.487 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.82ms
[D 2024-10-18 15:19:40.486 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.93ms
[D 2024-10-18 15:19:40.487 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 1.05ms
[D 2024-10-18 15:19:42.487 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.66ms
[D 2024-10-18 15:19:43.810 JupyterHub proxy:924] Proxy: Fetching GET http://proxy-api:8001/api/routes
[D 2024-10-18 15:19:43.817 JupyterHub proxy:393] Checking routes
[D 2024-10-18 15:19:44.487 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.66ms
[I 2024-10-18 15:19:44.838 JupyterHub login:45] User logged out: test user
[I 2024-10-18 15:19:44.846 JupyterHub log:192] 302 GET /hub/logout -> /hub/login (@::ffff:10.250.0.236) 18.84ms
[I 2024-10-18 15:19:44.979 JupyterHub _xsrf_utils:125] Setting new xsrf cookie for b'ac1f4e56f8b44f56ad0a8b3b63b3af3e:mpGonjT8zz7YvA32Kmuw9xBgrDTEx8UdSZ_GX7NuU1g=' {'path': '/hub/', 'max_age': 3600}
[I 2024-10-18 15:19:44.981 JupyterHub log:192] 200 GET /hub/login (@::ffff:10.250.0.236) 2.21ms
[D 2024-10-18 15:19:45.727 JupyterHub reflector:374] pods watcher timeout
[D 2024-10-18 15:19:45.727 JupyterHub reflector:289] Connecting pods watcher
[D 2024-10-18 15:19:45.731 JupyterHub reflector:374] events watcher timeout
[D 2024-10-18 15:19:45.731 JupyterHub reflector:289] Connecting events watcher
[D 2024-10-18 15:19:46.487 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.78ms
[I 2024-10-18 15:19:46.745 JupyterHub oauth2:99] OAuth redirect: https://jupyterhub.test.run/hub/oauth_callback
[D 2024-10-18 15:19:46.745 JupyterHub base:668] Setting cookie oauthenticator-state: {'httponly': True, 'secure': True, 'expires_days': 1}
[I 2024-10-18 15:19:46.746 JupyterHub log:192] 302 GET /hub/oauth_login?next= -> https://login.microsoftonline.com/<secret>/oauth2/authorize?response_type=code&redirect_uri=https%3A%2F%2Fjupyterhub.test.run%2Fhub%2Foauth_callback&client_id=<secret>=[secret] (@::ffff:10.250.0.236) 1.74ms
[D 2024-10-18 15:19:48.487 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.71ms
[D 2024-10-18 15:19:50.487 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.83ms
[D 2024-10-18 15:19:50.487 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.89ms
[D 2024-10-18 15:19:51.849 JupyterHub roles:282] Assigning default role to User test user
[D 2024-10-18 15:19:51.869 JupyterHub base:672] Setting cookie for test user: jupyterhub-hub-login
[D 2024-10-18 15:19:51.869 JupyterHub base:668] Setting cookie jupyterhub-hub-login: {'httponly': True, 'secure': True, 'path': '/hub/'}
[I 2024-10-18 15:19:51.870 JupyterHub _xsrf_utils:125] Setting new xsrf cookie for b'ac1f4e56f8b44f56ad0a8b3b63b3af3e:e5fc98b6cce44c4da75b476594750476' {'path': '/hub/'}
[I 2024-10-18 15:19:51.870 JupyterHub base:937] User logged in: test user
[I 2024-10-18 15:19:51.871 JupyterHub log:192] 302 GET /hub/oauth_callback?code=[secret]&state=[secret]&session_state=[secret] -> https://test_20user.jupyterhub.test.run/user/test%20user/ (test user@::ffff:100.64.5.1) 328.27ms
[I 2024-10-18 15:19:52.058 JupyterHub log:192] 302 GET /user/test%20user/ -> /hub/user/test%20user/ (@::ffff:100.64.0.1) 0.92ms
[I 2024-10-18 15:19:52.162 JupyterHub log:192] 302 GET /hub/user/test%20user/ -> /hub/login?next=%2Fhub%2Fuser%2Ftest%2520user%2F (@::ffff:100.64.0.1) 0.92ms
[I 2024-10-18 15:19:52.269 JupyterHub _xsrf_utils:125] Setting new xsrf cookie for b'None:lV2ZXie2z0Kh67XOWVwciMolraq6DhyPDDwKWNSyEGQ=' {'path': '/hub/', 'max_age': 3600}
[I 2024-10-18 15:19:52.271 JupyterHub log:192] 200 GET /hub/login?next=%2Fhub%2Fuser%2Ftest%2520user%2F (@::ffff:100.64.0.1) 2.26ms
[D 2024-10-18 15:19:52.421 JupyterHub log:192] 200 GET /hub/static/css/style.min.css?v=0a0508e2523bfc72e8e56c635fbe1778b63eac079a8364da92a699f0ef51a6f817edf0ba3bf533fd8d8c5ab18ca25cd9bd9d3c546ef56d264724a95575a6fae8 (@::ffff:100.64.0.1) 1.07ms
[D 2024-10-18 15:19:52.486 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.60ms
[D 2024-10-18 15:19:52.531 JupyterHub log:192] 200 GET /hub/static/components/bootstrap/dist/js/bootstrap.min.js?v=a014e9acc78d10a0a7a9fbaa29deac6ef17398542d9574b77b40bf446155d210fa43384757e3837da41b025998ebfab4b9b6f094033f9c226392b800df068bce (@::ffff:10.250.0.236) 0.87ms
[D 2024-10-18 15:19:52.533 JupyterHub log:192] 304 GET /hub/logo (@::ffff:100.64.0.1) 0.70ms
[D 2024-10-18 15:19:52.574 JupyterHub log:192] 200 GET /hub/static/components/jquery/dist/jquery.min.js?v=bf6089ed4698cb8270a8b0c8ad9508ff886a7a842278e98064d5c1790ca3a36d5d69d9f047ef196882554fc104da2c88eb5395f1ee8cf0f3f6ff8869408350fe (@::ffff:100.64.5.1) 0.99ms
[D 2024-10-18 15:19:52.575 JupyterHub log:192] 200 GET /hub/static/components/requirejs/require.js?v=1ff44af658602d913b22fca97c78f98945f47e76dacf9800f32f35350f05e9acda6dc710b8501579076f3980de02f02c97f5994ce1a9864c21865a42262d79ec (@::ffff:100.64.2.1) 0.76ms
[I 2024-10-18 15:19:53.067 JupyterHub log:192] 200 GET /hub/api (@100.64.0.46) 0.96ms
[D 2024-10-18 15:19:53.161 JupyterHub base:362] Recording first activity for <APIToken('6c77...', user='test user', client_id='jupyterhub')>
[D 2024-10-18 15:19:53.182 JupyterHub scopes:884] Checking access to /hub/api/users/test%20user/activity via scope users:activity
[D 2024-10-18 15:19:53.182 JupyterHub scopes:697] Argument-based access to /hub/api/users/test%20user/activity via users:activity
[D 2024-10-18 15:19:53.187 JupyterHub users:898] Activity for user test user: 2024-10-18T15:19:53.033236Z
[D 2024-10-18 15:19:53.187 JupyterHub users:916] Activity on server test user/: 2024-10-18T15:19:53.033236Z
[I 2024-10-18 15:19:53.198 JupyterHub log:192] 200 POST /hub/api/users/test%20user/activity (test user@100.64.0.46) 49.70ms
[I 2024-10-18 15:19:54.105 JupyterHub oauth2:99] OAuth redirect: https://jupyterhub.test.run/hub/oauth_callback
[D 2024-10-18 15:19:54.106 JupyterHub base:668] Setting cookie oauthenticator-state: {'httponly': True, 'secure': True, 'expires_days': 1}
[I 2024-10-18 15:19:54.106 JupyterHub log:192] 302 GET /hub/oauth_login?next=%2Fhub%2Fuser%2Ftest%2520user%2F -> https://login.microsoftonline.com/secretc/oauth2/authorize?response_type=code&redirect_uri=https%3A%2F%2Fjupyterhub.test.run%2Fhub%2Foauth_callback&client_id=[secret]&state=[secret] (@::ffff:100.64.2.1) 1.57ms
[D 2024-10-18 15:19:54.487 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.69ms
[D 2024-10-18 15:19:54.682 JupyterHub spawner:2821] pod jupyterhub/jupyter-test-20user events before launch: 2024-10-18T15:19:36.172957Z [Normal] Successfully assigned jupyterhub/jupyter-test-20user to shoot--data-d01-m14-eu01-3-z1-99d48-qm8ts
    2024-10-18T15:19:47Z [Normal] AttachVolume.Attach succeeded for volume "pv-shoot--data-d01-4d088277-99e6-42c1-8259-276385999606"
    2024-10-18T15:19:49Z [Normal] Pulling image "alpine/git"
    2024-10-18T15:19:50Z [Normal] Successfully pulled image "alpine/git" in 842ms (842ms including waiting)
    2024-10-18T15:19:50Z [Normal] Created container git-clone
    2024-10-18T15:19:50Z [Normal] Started container git-clone
    2024-10-18T15:19:51Z [Normal] Container image "docker-local.jfrog.io/jupyter-vscode:3.5.1-v9" already present on machine
    2024-10-18T15:19:51Z [Normal] Created container notebook
    2024-10-18T15:19:51Z [Normal] Started container notebook
[D 2024-10-18 15:19:54.701 JupyterHub spawner:1388] Polling subprocess every 30s
[D 2024-10-18 15:19:54.709 JupyterHub utils:286] Waiting 30s for server at http://100.64.0.46:8888/user/test%20user/
[D 2024-10-18 15:19:54.712 JupyterHub utils:303] Server at http://100.64.0.46:8888/user/test%20user/ responded with 302
[D 2024-10-18 15:19:54.712 JupyterHub utils:324] Server at http://100.64.0.46:8888/user/test%20user/ responded in 0.00s
[W 2024-10-18 15:19:54.712 JupyterHub _version:38] Single-user server has no version header, which means it is likely < 0.8. Expected 4.1.6
[I 2024-10-18 15:19:54.712 JupyterHub base:1090] User test user took 19.154 seconds to start
[I 2024-10-18 15:19:54.713 JupyterHub proxy:331] Adding user test user to proxy test_20user.jupyterhub.test.run/user/test%20user/ => http://100.64.0.46:8888
[D 2024-10-18 15:19:54.713 JupyterHub proxy:924] Proxy: Fetching POST http://proxy-api:8001/api/routes/test_20user.jupyterhub.test.run/user/test%20user
[I 2024-10-18 15:19:54.716 JupyterHub users:792] Server test user is ready
[I 2024-10-18 15:19:54.717 JupyterHub log:192] 200 GET /hub/api/users/test%20user/server/progress?_xsrf=[secret] (test user@::ffff:100.64.0.1) 18769.01ms
[D 2024-10-18 15:19:55.738 JupyterHub reflector:374] pods watcher timeout
[D 2024-10-18 15:19:55.738 JupyterHub reflector:289] Connecting pods watcher
[D 2024-10-18 15:19:55.741 JupyterHub reflector:374] events watcher timeout
[D 2024-10-18 15:19:55.741 JupyterHub reflector:289] Connecting events watcher
[D 2024-10-18 15:19:56.486 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.64ms
[W 2024-10-18 15:19:58.066 JupyterHub web:1873] 400 GET /hub/oauth_callback?code=[secret]&state=[secret]&session_state=[secret] (::ffff:100.64.0.1): OAuth state missing from cookies
[D 2024-10-18 15:19:58.067 JupyterHub base:1471] No template for 400
[W 2024-10-18 15:19:58.068 JupyterHub log:192] 400 GET /hub/oauth_callback?code=[secret]&state=[secret]&session_state=[secret] (test user@::ffff:100.64.0.1) 18.77ms

It looks like Z2JH doesn’t directly support subdomains. Configurable-Http-Proxy needs to be configured with the --host-routing flag. The following works for me with Z2JH version 4.0.0-beta.3, with certificates managed by cert-manager:

hub:
  config:
    JupyterHub:
      authenticator_class: github
      subdomain_host: jupyter.example.org
    GitHubOAuthenticator:
      oauth_callback_url: https://jupyter.example.org/hub/oauth_callback
      ...
proxy:
  chp:
    extraCommandLineFlags:
      - --host-routing

ingress:
  enabled: true
  hosts:
    - jupyter.example.org
    - "*.jupyter.example.org"
  tls:
    - hosts:
        - jupyter.example.org
        - "*.jupyter.example.org"
      secretName: jupyterhub-tls
  annotations:
    ...

it worked once and now for some reason it crashes malforming the redirect url:

https://jupyterhub.test.runhttps//jupyterhub.test.run/hub/api/oauth2/authorize?client_id=

I was using a loadbalancer service caught by and DNS A record and now I switched to ingress and ClusterIP service to resemble your setup.

Currently the singleuser starts successfully but, there is a redirect issue again. When I start the Server I get redirected to the user subdomain

https://test_20user.jupyterhub.test.run/user/test%20user/
404 page not found

logs from singeuser pod:

+ CMD=("$@")
+ exec /usr/bin/tini -s -- jupyterhub-singleuser
Non-spark-on-k8s command provided, proceeding in pass-through mode...
[W 2024-10-21 12:43:53.053 ServerApp] A `_jupyter_server_extension_points` function was not found in nbclassic. Instead, a `_jupyter_server_extension_paths` function was found and will be used for now. This function name will be deprecated in future releases of Jupyter Server.
[I 2024-10-21 12:43:53.057 ServerApp] jupyter_lsp | extension was successfully linked.
[I 2024-10-21 12:43:53.057 ServerApp] jupyter_resource_usage | extension was successfully linked.
[I 2024-10-21 12:43:53.062 ServerApp] jupyter_server_mathjax | extension was successfully linked.
[I 2024-10-21 12:43:53.062 ServerApp] jupyter_server_proxy | extension was successfully linked.
[I 2024-10-21 12:43:53.066 ServerApp] jupyter_server_terminals | extension was successfully linked.
[I 2024-10-21 12:43:53.066 ServerApp] jupyter_vscode_proxy | extension was successfully linked.
[I 2024-10-21 12:43:53.066 JupyterHubSingleUser] Starting jupyterhub single-user server extension version 4.1.5
[I 2024-10-21 12:43:53.067 JupyterHubSingleUser] Using default url from server extension lab: /lab
[I 2024-10-21 12:43:53.070 ServerApp] jupyterhub | extension was successfully linked.
[W 2024-10-21 12:43:53.072 LabApp] 'extra_template_paths' was found in both NotebookApp and ServerApp. This is likely a recent change. This config will only be set in NotebookApp. Please check if you should also config these traits in ServerApp for your purpose.
[I 2024-10-21 12:43:53.075 ServerApp] jupyterlab | extension was successfully linked.
[I 2024-10-21 12:43:53.075 ServerApp] jupyterlab_git | extension was successfully linked.
[W 2024-10-21 12:43:53.077 NotebookApp] 'extra_template_paths' was found in both NotebookApp and ServerApp. This is likely a recent change. This config will only be set in NotebookApp. Please check if you should also config these traits in ServerApp for your purpose.
[I 2024-10-21 12:43:53.079 ServerApp] nbclassic | extension was successfully linked.
[I 2024-10-21 12:43:53.079 ServerApp] nbdime | extension was successfully linked.
[W 2024-10-21 12:43:53.081 JupyterNotebookApp] 'extra_template_paths' was found in both NotebookApp and ServerApp. This is likely a recent change. This config will only be set in NotebookApp. Please check if you should also config these traits in ServerApp for your purpose.
[I 2024-10-21 12:43:53.083 ServerApp] notebook | extension was successfully linked.
[I 2024-10-21 12:43:53.085 ServerApp] Writing Jupyter server cookie secret to /home/jovyan/.local/share/jupyter/runtime/jupyter_cookie_secret
[I 2024-10-21 12:43:53.439 ServerApp] notebook_shim | extension was successfully linked.
/opt/conda/lib/python3.11/site-packages/jupyter_server/serverapp.py:2236: JupyterServerAuthWarning: Core endpoints without @allow_unauthenticated, @ws_authenticated, nor @web.authenticated:
- GET of JupyterHubLogoutHandler registered for /user/test%20user/logout
- GET of JupyterHubOAuthCallbackHandler registered for /user/test%20user/oauth_callback
  self.web_app = ServerWebApplication(
[I 2024-10-21 12:43:53.460 ServerApp] notebook_shim | extension was successfully loaded.
[I 2024-10-21 12:43:53.463 ServerApp] jupyter_lsp | extension was successfully loaded.
[I 2024-10-21 12:43:53.463 ServerApp] jupyter_resource_usage | extension was successfully loaded.
[I 2024-10-21 12:43:53.464 ServerApp] jupyter_server_mathjax | extension was successfully loaded.
[I 2024-10-21 12:43:53.481 ServerApp] jupyter_server_proxy | extension was successfully loaded.
[I 2024-10-21 12:43:53.482 ServerApp] jupyter_server_terminals | extension was successfully loaded.
[W 2024-10-21 12:43:53.483 ServerApp] jupyter_vscode_proxy | extension failed loading with message: ExtensionLoadingError('_load_jupyter_server_extension function was not found.')
    Traceback (most recent call last):
      File "/opt/conda/lib/python3.11/site-packages/jupyter_server/extension/manager.py", line 360, in load_extension
        extension.load_all_points(self.serverapp)
      File "/opt/conda/lib/python3.11/site-packages/jupyter_server/extension/manager.py", line 232, in load_all_points
        return [self.load_point(point_name, serverapp) for point_name in self.extension_points]
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/opt/conda/lib/python3.11/site-packages/jupyter_server/extension/manager.py", line 232, in <listcomp>
        return [self.load_point(point_name, serverapp) for point_name in self.extension_points]
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/opt/conda/lib/python3.11/site-packages/jupyter_server/extension/manager.py", line 223, in load_point
        return point.load(serverapp)
               ^^^^^^^^^^^^^^^^^^^^^
      File "/opt/conda/lib/python3.11/site-packages/jupyter_server/extension/manager.py", line 150, in load
        loader = self._get_loader()
                 ^^^^^^^^^^^^^^^^^^
      File "/opt/conda/lib/python3.11/site-packages/jupyter_server/extension/manager.py", line 119, in _get_loader
        loader = get_loader(loc)
                 ^^^^^^^^^^^^^^^
      File "/opt/conda/lib/python3.11/site-packages/jupyter_server/extension/utils.py", line 40, in get_loader
        raise ExtensionLoadingError(msg) from None
    jupyter_server.extension.utils.ExtensionLoadingError: _load_jupyter_server_extension function was not found.
[I 2024-10-21 12:43:53.494 JupyterHubSingleUser] Updating Hub with activity every 300 seconds
[I 2024-10-21 12:43:53.495 ServerApp] jupyterhub | extension was successfully loaded.
[I 2024-10-21 12:43:53.506 LabApp] JupyterLab extension loaded from /opt/conda/lib/python3.11/site-packages/jupyterlab
[I 2024-10-21 12:43:53.506 LabApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
[I 2024-10-21 12:43:53.507 LabApp] Extension Manager is 'pypi'.
[I 2024-10-21 12:43:53.524 ServerApp] jupyterlab | extension was successfully loaded.
[I 2024-10-21 12:43:53.530 ServerApp] jupyterlab_git | extension was successfully loaded.
[I 2024-10-21 12:43:53.534 ServerApp] nbclassic | extension was successfully loaded.
[I 2024-10-21 12:43:53.599 ServerApp] nbdime | extension was successfully loaded.
[I 2024-10-21 12:43:53.603 ServerApp] notebook | extension was successfully loaded.
[I 2024-10-21 12:43:53.604 ServerApp] Serving notebooks from local directory: /home/jovyan
[I 2024-10-21 12:43:53.604 ServerApp] Jupyter Server 2.14.0 is running at:
[I 2024-10-21 12:43:53.604 ServerApp] http://jupyter-test-20user:8888/user/test%20user/lab?token=...
[I 2024-10-21 12:43:53.604 ServerApp]     http://127.0.0.1:8888/user/test%20user/lab?token=...
[I 2024-10-21 12:43:53.604 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[I 2024-10-21 12:43:54.009 ServerApp] Skipped non-installed server(s): bash-language-server, dockerfile-language-server-nodejs, javascript-typescript-langserver, jedi-language-server, julia-language-server, pyright, python-language-server, python-lsp-server, r-languageserver, sql-language-server, texlab, typescript-language-server, unified-language-server, vscode-css-languageserver-bin, vscode-html-languageserver-bin, vscode-json-languageserver-bin, yaml-language-server
[I 2024-10-21 12:43:54.376 ServerApp] 302 GET /user/test%20user/ -> /user/test%20user/lab? (@100.64.4.44) 1.88ms

logs from hub:

[D 2024-10-21 12:47:33.464 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.73ms
[I 2024-10-21 12:47:33.685 JupyterHub oauth2:99] OAuth redirect: https://jupyterhub.test.run/hub/oauth_callback
[D 2024-10-21 12:47:33.685 JupyterHub base:668] Setting cookie oauthenticator-state: {'httponly': True, 'expires_days': 1}
[I 2024-10-21 12:47:33.686 JupyterHub log:192] 302 GET /hub/oauth_login?next= -> https://login.microsoftonline.com/<secret>/oauth2/authorize?response_type=code&redirect_uri=https%3A%2F%2Fjupyterhub.test.run%2Fhub%2Foauth_callback&client_id=<secret>=[secret] 
[D 2024-10-21 12:47:33.918 JupyterHub reflector:374] pods watcher timeout
[D 2024-10-21 12:47:33.918 JupyterHub reflector:289] Connecting pods watcher
[D 2024-10-21 12:47:34.056 JupyterHub reflector:374] pods watcher timeout
[D 2024-10-21 12:47:34.056 JupyterHub reflector:289] Connecting pods watcher
[D 2024-10-21 12:47:35.245 JupyterHub roles:282] Assigning default role to User test user
[D 2024-10-21 12:47:35.260 JupyterHub base:668] Setting cookie jupyterhub-session-id: {'httponly': True, 'path': '/', 'domain': 'jupyterhub.test.run'}
[D 2024-10-21 12:47:35.260 JupyterHub base:672] Setting cookie for test user: jupyterhub-hub-login
[D 2024-10-21 12:47:35.260 JupyterHub base:668] Setting cookie jupyterhub-hub-login: {'httponly': True, 'path': '/hub/'}
[I 2024-10-21 12:47:35.261 JupyterHub _xsrf_utils:125] Setting new xsrf cookie for b'cookie' {'path': '/hub/'}
[I 2024-10-21 12:47:35.261 JupyterHub base:937] User logged in: test user
[I 2024-10-21 12:47:35.262 JupyterHub log:192] 302 GET /hub/oauth_callback?code=[secret]&state=[secret]&session_state=[secret] -> https://test_20user.jupyterhub.test.run/user/test%20user/ 
[D 2024-10-21 12:47:35.464 JupyterHub log:192] 200 GET /hub/health (@10.250.0.236) 0.71ms

config:

hub:
  config:
     AzureAdOAuthenticator:
        allow_all: true
        username: unique_name
        oauth_callback_url: https://jupyterhub.test.run/hub/oauth_callback
        enable_auth_state: true
      JupyterHub:
        authenticator_class: azuread
        hub_connect_url: "http://hub.jupyterhub.svc.cluster.local:8081"   
  extraConfig:
    subdomain: |
      c.JupyterHub.subdomain_host = "https://jupyterhub.test.run" 
proxy:
  https:
    enabled: false
  chp:
    extraCommandLineFlags:
     - --host-routing
  service:
    type: ClusterIP
  https:
      enabled: false
  traefik:                                                                                                   
    hsts:
     includeSubdomains: true
singleuser:
  extraEnv:
    JUPYTERHUB_BASE_URL: 'https://jupyterhub.test.run/'
  cmd: jupyterhub-singleuser
  defaultUrl: null
ingress:
  enabled: true
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.tls: "true"
  ingressClassName: traefik
  hosts:
      - '*.jupyterhub.test.run'
      - 'jupyterhub.test.run'
  pathType: Prefix
  tls:
    - hosts:
        - '*.jupyterhub.test.run'
        - 'jupyterhub.test.run'
      secretName: wildcard-jupyterhub-tls

It’s possible there’s a bug in how special characters in usernames are escaped. Do you have a plain username you can test with to rule this out?

i switched to dummy authenticator and used a plain ‘test’ user and I fallback to the malformed url: https://jupyterhub.test.runhttps//jupyterhub.test.run/hub/api/oauth2/authorize?client_id=jupyterhub-user-test&redirect_uri=https%3A%2F%2Ftest.jupyterhub.test.run%2Fuser%2Ftest%2Foauth_callback&response_type=code&state=eyJ1dWlkIjogIjc1ZmUyM2JlYzQzYTRiMTNiZmMyMzNhOGVmODFjODVkIiwgIm5leHRfdXJsIjogIi91c2VyL3Rlc3QvbGFiPyJ9

logs:

[D 2024-10-21 14:38:37.583 JupyterHub log:192] 200 GET /hub/static/components/font-awesome/fonts/fontawesome-webfont.woff2?v=4.7.0 (@95.90.206.150) 1.51ms
[D 2024-10-21 14:38:37.600 JupyterHub roles:282] Assigning default role to User test
[D 2024-10-21 14:38:37.609 JupyterHub base:668] Setting cookie jupyterhub-session-id: {'httponly': True, 'path': '/', 'domain': 'jupyterhub.test.run'}
[D 2024-10-21 14:38:37.609 JupyterHub base:672] Setting cookie for test: jupyterhub-hub-login
[D 2024-10-21 14:38:37.609 JupyterHub base:668] Setting cookie jupyterhub-hub-login: {'httponly': True, 'path': '/hub/'}
[I 2024-10-21 14:38:37.609 JupyterHub _xsrf_utils:125] Setting new xsrf cookie for b'cookie' {'path': '/hub/'}
[I 2024-10-21 14:38:37.609 JupyterHub base:937] User logged in: test
[I 2024-10-21 14:38:37.610 JupyterHub log:192] 302 POST /hub/login?next=%2Fhub%2F -> /hub/ (test@95.90.206.150) 25.66ms
[I 2024-10-21 14:38:37.727 JupyterHub log:192] 302 GET /hub/ -> https://test.jupyterhub.test.run/user/test/ (test@95.90.206.150) 17.92ms
[D 2024-10-21 14:38:38.583 JupyterHub log:192] 200 GET /hub/static/css/style.min.css.map (@95.90.206.150) 0.81ms

Can you try without proxy.https.enabled? I don’t think the internal HTTPS proxy is designed to work with subdomains.

I get the same result

I removed JUPYTERHUB_BASE_URL env variable and it works fine with the simple usernames (no space, dots or any other special character). Can you give me a pointer for addressing the issue of escaping the special chars usernames?

I created a subclass of AzureAdOAuthenticator and changed the normalize_username function to clean up the username.
it works now :slight_smile:
thanks

1 Like

The beta release 4.0.0-beta.4 of Z2JH includes JupyterHub 5, which has some fixes for escaping usernames with subdomains.

However normalising the usernames is probably the safest solution, since you don’t have to worry about escaping it in every application that runs on top of Jupyter, e.g. anything in the future.

The main thing to be aware of is ensuring usernames are always unique.