{"record":{"id":"675a063a3c73508e","repo":"denoland/deno","slug":"failed-to-get-oidc-token-status-response","errorCode":null,"errorMessage":"Failed to get OIDC token: status {}, response: '{}'","messagePattern":"Failed to get OIDC token: status (.+?), response: '(.+?)'","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/tools/publish/mod.rs","lineNumber":782,"sourceCode":"        );\n\n        let response = client\n          .get(url.parse()?)?\n          .header(\n            http::header::AUTHORIZATION,\n            format!(\"Bearer {}\", oidc_config.token).parse()?,\n          )\n          .send()\n          .await\n          .context(\"Failed to get OIDC token\")?;\n        let status = response.status();\n        let text = crate::http_util::body_to_string(response)\n          .await\n          .with_context(|| {\n            format!(\"Failed to get OIDC token: status {}\", status)\n          })?;\n        if !status.is_success() {\n          bail!(\n            \"Failed to get OIDC token: status {}, response: '{}'\",\n            status,\n            text\n          );\n        }\n        let registry::OidcTokenResponse { value } = serde_json::from_str(&text)\n          .with_context(|| {\n            format!(\n              \"Failed to parse OIDC token: '{}' (status {})\",\n              text, status\n            )\n          })?;\n\n        let authorization: Rc<str> = format!(\"githuboidc {}\", value).into();\n        for pkg in chunked_packages.next().unwrap() {\n          authorizations.insert(\n            (pkg.scope.clone(), pkg.package.clone(), pkg.version.clone()),\n            authorization.clone(),","sourceCodeStart":764,"sourceCodeEnd":800,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/cli/tools/publish/mod.rs#L764-L800","documentation":"When publishing tokenless from GitHub Actions via OIDC, Deno mints a JSR-audience token by calling the Actions OIDC endpoint (`ACTIONS_ID_TOKEN_REQUEST_URL`) with the job's bearer token. Any non-2xx reply produces this error with the HTTP status and the response body. Typical bodies are 'token expired' (OIDC tokens are short-lived) or permission/audience errors from GitHub.","triggerScenarios":"Auth method resolved to OIDC (`GITHUB_ACTIONS=true`, `ACTIONS_ID_TOKEN_REQUEST_URL`/`ACTIONS_ID_TOKEN_REQUEST_TOKEN` present, no `--token`) and the token endpoint answered with status >= 400 — e.g. 403 expired token on long-running multi-chunk publishes, 401 when the job lacks id-token permission.","commonSituations":"Slow CI publish jobs whose minted token expires; workflows missing `permissions: id-token: write`; transient GitHub OIDC service errors; large workspaces published in 16-package chunks.","solutions":["Re-run the job — an expired/short-lived OIDC token is the most common cause and a retry mints a fresh one.","Add `permissions: id-token: write` (and `contents: read`) to the publishing job or workflow.","If it persists, publish with an explicit token: `deno publish --token <JSR_TOKEN>`."],"exampleFix":"# .github/workflows/publish.yml (before)\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - run: deno publish\n# after\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    permissions:\n      id-token: write\n      contents: read\n    steps:\n      - uses: actions/checkout@v4\n      - run: deno publish","handlingStrategy":"retry","validationCode":"#!/usr/bin/env bash\n# verify the OIDC prerequisites before publishing\n[ \"${GITHUB_ACTIONS:-}\" = \"true\" ] || { echo \"not in GitHub Actions — use --token or skip\" >&2; exit 1; }\n[ -n \"${ACTIONS_ID_TOKEN_REQUEST_TOKEN:-}\" ] || { echo \"job needs permissions: id-token: write\" >&2; exit 1; }","typeGuard":null,"tryCatchPattern":"#!/usr/bin/env bash\nfor attempt in 1 2 3; do\n  out=\"$(deno publish 2>&1)\" && exit 0\n  if printf '%s' \"$out\" | grep -q 'Failed to get OIDC token'; then\n    echo \"OIDC mint failed (attempt $attempt) — backing off\" >&2\n    sleep $((attempt * 30))   # a retry mints a fresh, unexpired token\n    continue\n  fi\n  printf '%s\\n' \"$out\" >&2; exit 1\ndone\nexit 1","preventionTips":["Declare `permissions: id-token: write, contents: read` on the publishing job.","Keep publish jobs short — OIDC tokens expire, and long multi-package runs are the main trigger.","Fall back to `--token <JSR_TOKEN>` (stored as a secret) when retries keep failing."],"tags":["publish","oidc","github-actions","auth","network"],"backgroundTag":"oidc-token-request-failed","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}