{"record":{"id":"9e340d2a3e4aeeb2","repo":"denoland/deno","slug":"no-certificate-chain-returned","errorCode":null,"errorMessage":"No certificate chain returned","messagePattern":"No certificate chain returned","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"cli/tools/publish/provenance.rs","lineNumber":531,"sourceCode":"          content: public_key,\n        },\n        proof_of_possession: BASE64_STANDARD.encode(challenge.as_ref()),\n      },\n    };\n\n    let response = self\n      .http_client\n      .post_json(url.parse()?, &request_body)?\n      .send()\n      .await?;\n\n    let body: SigningCertificateResponse =\n      http_util::body_to_json(response).await?;\n\n    let key = body\n      .signed_certificate_embedded_sct\n      .or(body.signed_certificate_detached_sct)\n      .ok_or_else(|| anyhow::anyhow!(\"No certificate chain returned\"))?;\n    Ok(key.chain.certificates)\n  }\n\n  async fn gha_request_token(&self, aud: &str) -> Result<String, AnyError> {\n    let Ok(req_url) = env::var(\"ACTIONS_ID_TOKEN_REQUEST_URL\") else {\n      bail!(\"Not running in GitHub Actions\");\n    };\n\n    let Some(token) = gha_oidc_token() else {\n      bail!(\"No OIDC token available\");\n    };\n\n    let mut url = req_url.parse::<Url>()?;\n    url.query_pairs_mut().append_pair(\"audience\", aud);\n    let res_bytes = self\n      .http_client\n      .get(url)?\n      .header(","sourceCodeStart":513,"sourceCodeEnd":549,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/cli/tools/publish/provenance.rs#L513-L549","documentation":"During provenance signing Deno requests a short-lived signing certificate from Fulcio (Sigstore's CA) and expects the response to carry either an embedded or detached signed-certificate-timestamp chain. When both fields are absent, there is no usable certificate chain and this error is thrown. It means Fulcio answered with a payload Deno could not use — outage, API change, or a mangled response.","triggerScenarios":"`deno publish --provenance` where fulcio.sigstore.dev returns an error page or a changed response shape that deserializes with both SCT fields empty.","commonSituations":"Fulcio incidents or deployments; an old Deno version against a changed Fulcio API; proxies returning HTML error pages instead of JSON.","solutions":["Retry the publish after a short wait — Fulcio hiccups are usually transient","Update Deno to the latest patch release","Verify https://fulcio.sigstore.dev is reachable and not intercepted by a proxy","Report it with debug logs if it persists"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"# preflight: is Fulcio reachable from this runner?\ncurl -fsS https://fulcio.sigstore.dev/ > /dev/null \\\n  || { echo \"fulcio.sigstore.dev unreachable\" >&2; exit 1; }","typeGuard":null,"tryCatchPattern":"Same bounded-retry pattern as Rekor: retry `deno publish --provenance` with backoff (2-3 attempts), bumping the version if a partial upload consumed it; escalate to an issue only if it persists on the latest Deno.","preventionTips":["Keep Deno updated so the Fulcio client matches the current API shape","Ensure no proxy rewrites Fulcio responses (HTML error pages deserialize to empty chains)","Check Sigstore service status before starting a release"],"tags":["publish","provenance","fulcio","sigstore","network"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}