{"record":{"id":"91de588633cb48ea","repo":"rancher/rancher","slug":"github-getaccesstoken-post-url-v-received-error-91de58","errorCode":null,"errorMessage":"github getAccessToken: POST url %v received error from github, err: %v","messagePattern":"github getAccessToken: POST url (.+?) received error from github, err: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/auth/providers/githubapp/githubapp_client.go","lineNumber":46,"sourceCode":"\tmaxGitHubBodySize int64 = 1024 * 1024 * 5\n)\n\n// githubAppClient implements client for GitHub using a GitHub App.\ntype githubAppClient struct {\n\thttpClient *http.Client\n}\n\nfunc (g *githubAppClient) getAccessToken(ctx context.Context, code string, config *apiv3.GithubAppConfig) (string, error) {\n\tform := url.Values{}\n\tform.Add(\"client_id\", config.ClientID)\n\tform.Add(\"client_secret\", config.ClientSecret)\n\tform.Add(\"code\", code)\n\n\turl := getAPIURL(\"TOKEN\", config)\n\n\tb, err := g.postToGithub(ctx, url, form)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"github getAccessToken: POST url %v received error from github, err: %v\", url, err)\n\t}\n\n\t// Decode the response\n\tvar respMap map[string]any\n\n\tif err := json.Unmarshal(b, &respMap); err != nil {\n\t\treturn \"\", fmt.Errorf(\"github getAccessToken: received error unmarshalling response body, err: %v\", err)\n\t}\n\n\tif respMap[\"error\"] != nil {\n\t\tdesc := respMap[\"error_description\"]\n\t\treturn \"\", fmt.Errorf(\"github getAccessToken: received error from github %v, description from github %v\", respMap[\"error\"], desc)\n\t}\n\n\tacessToken, ok := respMap[\"access_token\"].(string)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"github getAccessToken: received error reading accessToken from response %v\", respMap)\n\t}","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/rancher/rancher/blob/932558d4e68565aff2d2f36e89ec4a391b06e7c5/pkg/auth/providers/githubapp/githubapp_client.go#L28-L64","documentation":"githubAppClient.getAccessToken exchanges an OAuth code for a token via postToGithub and wraps any transport/HTTP-level failure with the exact URL posted to. The underlying postToGithub error may be a network failure, a non-2xx status, or a rejected POST (bad client_id/client_secret, expired or reused code, redirect mismatch).","triggerScenarios":"POST to the configured TOKEN endpoint (github.com/login/oauth/access_token or GHE equivalent) with wrong ClientSecret in GithubAppConfig; the device-flow/user code already redeemed or expired (codes are single-use, ~10 min TTL); redirect_uri not matching the app settings; GitHub unreachable or a GHE endpoint typo.","commonSituations":"Browser back-button or refresh re-submitting the callback with the same code; clock-sensitive logins during NTP drift; client secret rotated on GitHub but stale in the Rancher secret; GHE URL missing scheme.","solutions":["If the error contains a 401/400 status: verify ClientID/ClientSecret in the GithubAppConfig secret exactly match the GitHub App.","If the code is reused/expired: have the user restart the login from the auth page instead of refreshing the callback URL.","Confirm the app's callback/redirect URL registered on GitHub matches the RedirectURL the provider sends.","For GHE, verify the endpoint URL and network path (curl the TOKEN endpoint from inside the pod)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// pre-flight the OAuth exchange inputs\nif config.ClientID == \"\" || config.ClientSecret == \"\" {\n    return errors.New(\"github app client id/secret missing in GithubAppConfig\")\n}\nif code == \"\" {\n    return errors.New(\"empty OAuth code — restart login instead of reusing the callback\")\n}","typeGuard":null,"tryCatchPattern":"b, err := g.postToGithub(ctx, url, form)\nif err != nil {\n    // OAuth codes are single-use: retrying the same form fails again.\n    // Network/5xx causes are retryable only with a freshly issued code.\n    return \"\", fmt.Errorf(\"github getAccessToken: POST url %v received error from github, err: %v\", url, err)\n}","preventionTips":["Never re-render or refresh the OAuth callback URL — always restart from the login page.","Keep ClientID/ClientSecret synced with the GitHub App settings (rotate together).","Register the exact callback URL on the GitHub App and verify redirects match.","curl the token endpoint from the pod to rule out egress/proxy issues when debugging."],"tags":["github-app","oauth","token-exchange","auth"],"backgroundTag":null,"analyzedSha":"932558d4e68565aff2d2f36e89ec4a391b06e7c5","analyzedAt":"2026-08-16T04:37:02.125Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}