Troubleshooting
When Positron won’t start for a user, the cause is almost always in one of four places: the launcher extension (user env), the verifier service (Hub), the license/signing key, or the install itself (arch/version). This page is organized by symptom.
Where to look first
Most answers are in the logs. The verifier runs as a managed JupyterHub service, so its output lands in the Hub log:
# Hub + verifier service (the verifier logs with the "positron-license" name)
journalctl -u jupyterhub --no-pager | grep -i positron-license
# Full Hub log (spawn errors, service registration)
journalctl -u jupyterhub --no-pager -n 200# Hub + verifier
docker compose logs hub | grep -i positron-license
# A user's single-user container (name shown by `docker ps`)
docker logs <jupyter-USERNAME-container>The single-user server’s log (available from the JupyterHub UI under the user’s server, or the spawner logs) shows what jupyter-positron-server and positron-server reported at launch.
The Positron launcher tile doesn’t appear
The tile is provided by jupyter-positron-server via jupyter-server-proxy, in the user environment.
Check — in the user env:
# Is the extension installed and jupyter_server_proxy enabled?
/opt/tljh/user/bin/pip show jupyter-positron-server
/opt/tljh/user/bin/jupyter server extension listFixes:
Extension missing → install it in the user env and enable the proxy:
/opt/tljh/user/bin/pip install 'jupyter-positron-server>=0.0.5' /opt/tljh/user/bin/jupyter server extension enable --sys-prefix jupyter_server_proxyInstalled but no tile → confirm
JSP_POSITRON_LAUNCHER_DISABLEDis not set in the spawner environment (any value hides the tile).Restart the user’s server (stop and start it from the JupyterHub UI) — the extension is picked up on server start, not on Hub reload.
The tile is there, but Positron never loads
The launcher runs, but positron-server fails to start.
Check the single-user server log for the failing step, then:
positron-server: command not found/ binary not found —positron-serverisn’t on the sessionPATH. Confirm the spawner sets it:# TLJH: jupyterhub_config.py c.Spawner.environment = { "PATH": "/opt/positron-server/bin:" + os.environ.get("PATH", "/usr/local/bin:/usr/bin:/bin"), ... }In the docker template the binary is on
PATHvia the single-user image’sENV, and the spawner intentionally does not overridePATH.Hangs or license error — the mint step is failing. See the two sections below.
The verifier service isn’t running or registered
Check whether the Hub registered the positron-license service and it is listening:
journalctl -u jupyterhub --no-pager | grep -i positron-license
# Should show the service starting; if there is nothing, it was never registered.Fixes:
No mention at all → the service config wasn’t loaded. Confirm your
jupyterhub_config.py(or the generatedpositron-license.pyinjupyterhub_config.d/) contains thec.JupyterHub.servicesblock, then reload:tljh-config reload # TLJH # or: systemctl restart jupyterhub # docker: docker compose restart hubService starts then dies → check the command exists in the Hub env:
/opt/tljh/hub/bin/pip show jupyter-positron-verifier ls -l /opt/tljh/hub/bin/positron-verifierPort conflict on
VERIFIER_PORT(default10101) → another process holds the port; changeVERIFIER_PORTand updatePOSITRON_LICENSE_MINTING_ENDPOINTto match.
License / mint errors
The verifier confirms entitlement with license-manager and mints a signed, session-bound token. Common failures:
Signing key not readable — the verifier runs as the Hub service account and reads
POSITRON_MINTING_KEY_FILE. Confirm the file exists and is readable by that account:ls -l /etc/positron/signing-key.pem # mode 600, owned by the Hub userMinting endpoint unreachable / wrong URL —
POSITRON_LICENSE_MINTING_ENDPOINTmust point at the Hub-proxied service path. TLJH:http://127.0.0.1:10101/services/positron-license/mint; docker:http://hub:${VERIFIER_PORT}/services/positron-license/mint.403/ authorization errors from the mint call — the service role is missing scopes. Confirm thec.JupyterHub.load_rolesblock grants thepositron-licenseserviceread:users.
Install-time failures
- Download fails (
curl403/404) — thePOSITRON_VERSION/POSITRON_ARCHcombination doesn’t exist on the CDN. Verify the version string, or download the tarball yourself and passPOSITRON_TARBALL=./positron-server.tar.gz.
docker-compose specifics
Hub container exits at boot with
Positron … not found or empty at …— a secret wasn’t placed. Copysigning-key.pemandlicense.licintodocker/secrets/(a missing bind-mount source makes Docker create an empty directory, which is why the Hub checks at boot):cp /path/to/signing-key.pem secrets/signing-key.pem cp /path/to/license.lic secrets/license.lic docker compose up -dSingle-user containers fail to spawn — the single-user image must be built (
docker compose build hub singleuser) and itsjupyterhub-singleuserversion must be compatible with the Hub’s JupyterHub (see below).Anyone can log in — that’s
DummyAuthenticator, the template default. Replace it inhub/jupyterhub_config.pyand rebuild before any real use.
Still stuck?
Open an issue at github.com/posit-dev/jupyter-positron-server with the relevant Hub and single-user log excerpts, your Positron version, and which deployment path you used.