{"record":{"id":"958a4df40ffa9972","repo":"hashicorp/packer","slug":"create-github-oidc-request-w","errorCode":null,"errorMessage":"create GitHub OIDC request: %w","messagePattern":"create GitHub OIDC request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/attestation/sign_keyless.go","lineNumber":338,"sourceCode":"\trequestURL := strings.TrimSpace(env[\"ACTIONS_ID_TOKEN_REQUEST_URL\"])\n\trequestToken := strings.TrimSpace(env[\"ACTIONS_ID_TOKEN_REQUEST_TOKEN\"])\n\tif requestURL == \"\" || requestToken == \"\" {\n\t\treturn \"\", nil\n\t}\n\n\tparsedURL, err := url.Parse(requestURL)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"parse GitHub OIDC request URL: %w\", err)\n\t}\n\tquery := parsedURL.Query()\n\tif query.Get(\"audience\") == \"\" {\n\t\tquery.Set(\"audience\", \"sigstore\")\n\t\tparsedURL.RawQuery = query.Encode()\n\t}\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, parsedURL.String(), nil)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"create GitHub OIDC request: %w\", err)\n\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 {","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/internal/attestation/sign_keyless.go#L320-L356","documentation":"http.NewRequestWithContext failed to build the GET request to GitHub's OIDC token endpoint. Given that the URL already parsed successfully, this almost always means the constructed URL string (after adding the audience query parameter) is invalid — practically only via an invalid method/URL combination or context-related construction edge cases.","triggerScenarios":"resolveGitHubActionsIDToken calls http.NewRequestWithContext with the audience-augmented ACTIONS_ID_TOKEN_REQUEST_URL, and Go's request constructor rejects the resulting absolute URL (e.g. a scheme-less URL that only worked for url.Parse).","commonSituations":"ACTIONS_ID_TOKEN_REQUEST_URL overridden to a relative or scheme-less value like \"localhost/token\" that url.Parse accepts but the HTTP client's request constructor deems invalid for a request target.","solutions":["Ensure ACTIONS_ID_TOKEN_REQUEST_URL is an absolute URL with scheme and host (https://...).","Compare the URL string before and after audience-parameter augmentation to spot corruption.","Check the wrapped error's URL field for the exact rejected value.","Bypass by exporting SIGSTORE_ID_TOKEN directly if the endpoint override cannot be fixed."],"exampleFix":"// before\nenv[\"ACTIONS_ID_TOKEN_REQUEST_URL\"] = \"localhost:8080/tokens\"\n// after\nenv[\"ACTIONS_ID_TOKEN_REQUEST_URL\"] = \"http://localhost:8080/tokens\"","handlingStrategy":"validation","validationCode":"raw := strings.TrimSpace(env[\"ACTIONS_ID_TOKEN_REQUEST_URL\"])\nif u, err := url.Parse(raw); err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"ACTIONS_ID_TOKEN_REQUEST_URL must be an absolute URL with scheme and host\")\n}","typeGuard":"func isAbsoluteHTTPURL(raw string) bool {\n    u, err := url.Parse(strings.TrimSpace(raw))\n    return err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\") && u.Host != \"\"\n}","tryCatchPattern":"signer, err := newKeylessSigner(ctx, cfg)\nif err != nil && strings.Contains(err.Error(), \"create GitHub OIDC request\") {\n    return fmt.Errorf(\"could not build OIDC token request; check ACTIONS_ID_TOKEN_REQUEST_URL is absolute: %w\", err)\n}","preventionTips":["Use absolute URLs (with scheme) when overriding the OIDC endpoint.","Test overrides by hitting the URL with curl before wiring it in.","Keep the default GitHub-injected value whenever possible.","Sanitize the URL string after appending the audience query parameter."],"tags":["go","http","github-actions","oidc"],"backgroundTag":"invalid-http-request","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"}