{"record":{"id":"647f59dfdc064c34","repo":"nicolargo/glances","slug":"jwt-authentication-is-not-available","errorCode":null,"errorMessage":"JWT authentication is not available","messagePattern":"JWT authentication is not available","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"glances/jwt_utils.py","lineNumber":73,"sourceCode":"    @property\n    def expire_minutes(self) -> int:\n        \"\"\"Return the token expiration time in minutes.\"\"\"\n        return self._expire_minutes\n\n    def create_access_token(self, username: str) -> str:\n        \"\"\"Create a JWT access token for the given username.\n\n        Args:\n            username: The username to encode in the token\n\n        Returns:\n            Encoded JWT token string\n\n        Raises:\n            RuntimeError: If JWT is not available\n        \"\"\"\n        if not self.is_available:\n            raise RuntimeError(\"JWT authentication is not available\")\n\n        expire = datetime.now(timezone.utc) + timedelta(minutes=self._expire_minutes)\n        to_encode = {\n            \"sub\": username,\n            \"exp\": expire,\n            \"iat\": datetime.now(timezone.utc),\n            \"iss\": \"glances\",\n        }\n        return jwt.encode(to_encode, self._secret_key, algorithm=self.ALGORITHM)\n\n    def verify_token(self, token: str) -> str | None:\n        \"\"\"Verify a JWT token and extract the username.\n\n        Args:\n            token: The JWT token to verify\n\n        Returns:\n            Username if valid, None otherwise","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/nicolargo/glances/blob/a240d8dfb3105a38b5964357ec21768594b0e83e/glances/jwt_utils.py#L55-L91","documentation":"create_access_token() refuses to mint JWTs when the GlancesJWT instance is not backed by a usable secret — is_available is False because python-jose (or the secret) is missing. The RuntimeError surfaces when the REST API /api/4/token endpoint tries to generate a token, which instead reports HTTP 501 to clients.","triggerScenarios":"Running glances -w --password without the [jwt]/[api] secret configured, or without the python-jose extra installed; then POSTing to /api/4/token, whose _api_token handler calls create_access_token and this raises before the HTTP 501 mapping.","commonSituations":"Users enabling --password but skipping 'pip install glances[api]' (which pulls python-jose); first run where no JWT secret file was generated yet; container images built without the api extra.","solutions":["Install the dependency: pip install 'glances[api]' (installs python-jose).","Ensure a JWT secret exists — start Glances once with --password so the secret file is generated, or set it in the config under the appropriate section.","Verify afterwards with curl -X POST http://localhost:61208/api/4/token."],"exampleFix":"# before\ndocker run glances\n# 501 JWT authentication is not available\n\n# after\ndocker run glances sh -c 'pip install \"glances[api]\" && glances -w --password'","handlingStrategy":"validation","validationCode":"from glances.jwt_utils import GlancesJWT\njwt = GlancesJWT(config)\nif not jwt.is_available:\n    raise SystemExit('Install glances[api] / configure JWT secret before using /api/4/token')","typeGuard":null,"tryCatchPattern":"try:\n    token = jwt.create_access_token('user')\nexcept RuntimeError:\n    # JWT unavailable: fall back to basic auth for API access","preventionTips":["Install the [api] extra in deployment images.","Run once with --password to generate the secret.","Check is_available before enabling token-based tooling."],"tags":["jwt","authentication","missing-dependency","rest-api"],"backgroundTag":"jwt-library-missing","analyzedSha":"a240d8dfb3105a38b5964357ec21768594b0e83e","analyzedAt":"2026-08-27T19:15:19.178Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}