{"record":{"id":"e6d286b370710777","repo":"hashicorp/packer","slug":"decode-github-oidc-token-response-w","errorCode":null,"errorMessage":"decode GitHub OIDC token response: %w","messagePattern":"decode GitHub OIDC token response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/attestation/sign_keyless.go","lineNumber":357,"sourceCode":"\t}\n\treq.Header.Set(\"Authorization\", \"Bearer \"+requestToken)\n\n\tclient := &http.Client{Timeout: 30 * time.Second}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"request GitHub OIDC token: %w\", err)\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\tif resp.StatusCode/100 != 2 {\n\t\treturn \"\", fmt.Errorf(\"request GitHub OIDC token: unexpected status %s\", resp.Status)\n\t}\n\n\tvar payload struct {\n\t\tValue string `json:\"value\"`\n\t}\n\tif err := json.NewDecoder(resp.Body).Decode(&payload); err != nil {\n\t\treturn \"\", fmt.Errorf(\"decode GitHub OIDC token response: %w\", err)\n\t}\n\treturn strings.TrimSpace(payload.Value), nil\n}\n","sourceCodeStart":339,"sourceCodeEnd":361,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/internal/attestation/sign_keyless.go#L339-L361","documentation":"resolveGitHubActionsIDToken fetches the ambient OIDC token exposed by GitHub Actions and decodes the JSON response body expecting a {\"value\": \"<jwt>\"} shape. This error wraps any failure of json.Decoder on the HTTP response body: malformed JSON, an unexpected schema (e.g. a different key name or an error object returned by the endpoint), or an I/O error while reading the body. It is thrown because a token that cannot be parsed is useless downstream — the caller needs the raw JWT string to sign attestations.","triggerScenarios":"Calling resolveGitHubActionsIDToken when the OIDC endpoint (ACTIONS_ID_TOKEN_REQUEST_URL with ACTIONS_ID_TOKEN_REQUEST_TOKEN auth) returns a 200 whose body is not the expected {\"value\": ...} JSON — e.g. an HTML error page from a proxy, a truncated response, or the response format changed.","commonSituations":"Running inside GitHub Actions but behind a corporate proxy that rewrites responses; wrong ACTIONS_ID_TOKEN_REQUEST_URL pointing at a non-OIDC endpoint; GitHub API behavior/permission changes (job lacks 'id-token: write' permission and an error body is returned that fails JSON decoding); flaky network truncating the response body mid-decode.","solutions":["Verify the workflow job grants 'permissions: id-token: write' so the OIDC endpoint returns a valid token response instead of an error payload.","Check ACTIONS_ID_TOKEN_REQUEST_URL and ACTIONS_ID_TOKEN_REQUEST_TOKEN env vars are set and not pointing at a proxy or wrong host.","Re-run the job to rule out a truncated/flaky response body; inspect resp.Body content (dump it before decoding) to see what was actually returned.","If behind a proxy, bypass it for the OIDC request or fix TLS interception that mangles the body.","Upgrade to the latest version of the tool in case the expected response schema changed upstream."],"exampleFix":"// before\nvar payload struct {\n\tValue string `json:\"value\"`\n}\nif err := json.NewDecoder(resp.Body).Decode(&payload); err != nil {\n\treturn \"\", fmt.Errorf(\"decode GitHub OIDC token response: %w\", err)\n}\n// after\nbody, _ := io.ReadAll(resp.Body)\nif resp.StatusCode != http.StatusOK {\n\treturn \"\", fmt.Errorf(\"github OIDC request failed: %s: %s\", resp.Status, body)\n}\nvar payload struct {\n\tValue string `json:\"value\"`\n}\nif err := json.Unmarshal(body, &payload); err != nil {\n\treturn \"\", fmt.Errorf(\"decode GitHub OIDC token response %q: %w\", body, err)\n}","handlingStrategy":"try-catch","validationCode":"if os.Getenv(\"ACTIONS_ID_TOKEN_REQUEST_URL\") == \"\" || os.Getenv(\"ACTIONS_ID_TOKEN_REQUEST_TOKEN\") == \"\" {\n\treturn errors.New(\"not running in a GitHub Actions OIDC-enabled job: set permissions: id-token: write\")\n}","typeGuard":null,"tryCatchPattern":"token, err := resolveGitHubActionsIDToken(ctx)\nif err != nil {\n\tvar decErr *json.SyntaxError\n\tif strings.Contains(err.Error(), \"decode GitHub OIDC token response\") {\n\t\t// log response status/body, check id-token: write and proxy settings, retry once\n\t}\n\treturn fmt.Errorf(\"obtaining GHA id token: %w\", err)\n}","preventionTips":["Always set permissions: id-token: write on the workflow/job.","Confirm ACTIONS_ID_TOKEN_REQUEST_URL/TOKEN are present before calling.","Inspect HTTP status and raw body before decoding; fail fast with the body on non-200.","Exclude the OIDC endpoint from corporate proxies/TLS interception.","Keep the tool up to date in case the GitHub response schema changes."],"tags":["http","json","oidc","github-actions"],"backgroundTag":"json-decode-failed","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}