{"record":{"id":"fe5b917afe89f76f","repo":"windmill-labs/windmill","slug":"error-requesting-oidc-token-from-url-e","errorCode":null,"errorMessage":"Error requesting oidc token from {url}: {e:#?}","messagePattern":"Error requesting oidc token from (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/windmill-common/src/client.rs","lineNumber":91,"sourceCode":"    pub async fn get_id_token(&self, audience: &str) -> anyhow::Result<String> {\n        let url = format!(\n            \"{}/api/w/{}/oidc/token/{}\",\n            self.base_internal_url, self.workspace, audience\n        );\n        let response = self\n            .force_client\n            .as_ref()\n            .unwrap_or(&HTTP_CLIENT)\n            .post(&url)\n            .header(\n                reqwest::header::AUTHORIZATION,\n                reqwest::header::HeaderValue::from_str(&format!(\"Bearer {}\", self.token))?,\n            )\n            .send()\n            .await\n            .map_err(|e| {\n                tracing::error!(\"Error requesting oidc token from {url}: {e:#?}\");\n                anyhow::anyhow!(\"Error requesting oidc token from {url}: {e:#?}\")\n            })?;\n\n        match response.status().as_u16() {\n            200u16 => Ok(response.text().await.context(\"reading oidc token body\")?),\n            status => {\n                let body = response.text().await.unwrap_or_default();\n                Err(anyhow::anyhow!(\n                    \"oidc token request to {url} failed with status {status}: {body}\"\n                ))\n            }\n        }\n    }\n\n    pub async fn get_resource_value<T: DeserializeOwned>(&self, path: &str) -> anyhow::Result<T> {\n        let url = format!(\n            \"{}/api/w/{}/resources/get_value/{}\",\n            self.base_internal_url, self.workspace, path\n        );","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-common/src/client.rs#L73-L109","documentation":"AuthedClient::get_id_token POSTs to the workspace's OIDC token endpoint (/api/w/{ws}/oidc/token/{audience}) to mint a short-lived token for a given audience. This error is thrown when the HTTP request itself fails at the transport level — connection refused, DNS failure, TLS error, timeout — before any status code is returned. The reqwest error is formatted with {e:#?} so the full error chain is embedded in the message.","triggerScenarios":"Calling get_id_token (e.g. from a worker or script needing a service token) when base_internal_url points to an unreachable or wrong host/port, the backend is down or restarting, DNS cannot resolve the hostname, or a proxy/firewall blocks the connection. Also on TLS certificate failures and reqwest total-timeout expiry on HTTP_CLIENT.","commonSituations":"Self-hosted workers with a misconfigured BASE_URL/internal URL, Kubernetes/Docker networking where the worker cannot reach the API service name, backend temporarily unavailable during rolling deploys, split-horizon DNS where the internal URL resolves only inside the cluster.","solutions":["Verify base_internal_url is reachable from the process calling get_id_token: curl -v <base_internal_url>/api/health","Check the backend is running and listening on the port in base_internal_url (ss -ltnp / docker ps)","Fix DNS/hostname: use the in-cluster service name for workers, not an external URL","If TLS is involved, confirm the CA is trusted by the worker container or use the proper scheme (http vs https)","For transient outages, wrap the call in a bounded retry with backoff"],"exampleFix":"// before: guessing the URL\nlet client = AuthedClient::new(\"http://windmill.internal:9000\".into(), ws, token, None);\n// after: build from an env-configured, health-checked base URL\nlet base = std::env::var(\"WM_BASE_INTERNAL_URL\").expect(\"WM_BASE_INTERNAL_URL set\");\nreqwest::get(format!(\"{base}/api/health\")).await.expect(\"backend reachable before auth\");\nlet client = AuthedClient::new(base, ws, token, None);","handlingStrategy":"retry","validationCode":"let health = reqwest::get(format!(\"{base_internal_url}/api/health\")).await;\nassert!(health.is_ok(), \"backend unreachable at {base_internal_url} before calling get_id_token\");","typeGuard":null,"tryCatchPattern":"match client.get_id_token(aud).await {\n    Ok(tok) => tok,\n    Err(e) if e.to_string().contains(\"Error requesting oidc token\") => {\n        // transport-level failure: log and retry with backoff\n        tokio::time::sleep(Duration::from_secs(2)).await;\n        client.get_id_token(aud).await.context(\"oidc token after retry\")?\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Health-check base_internal_url at worker startup and fail fast with a clear message","Use in-cluster service DNS for workers, never external URLs that may not resolve inside the network","Set consistent http/https scheme and trusted CAs across the deployment","Wrap token fetches in bounded exponential backoff for rolling-deploy windows"],"tags":["network","http","oidc","rust"],"backgroundTag":"http-request-transport-failed","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}