{"record":{"id":"4bec1332a56a6c2f","repo":"github/github-mcp-server","slug":"requesting-device-code-w","errorCode":null,"errorMessage":"requesting device code: %w","messagePattern":"requesting device code: %w","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/oauth/flow.go","lineNumber":166,"sourceCode":"\t\t\t})\n\t\t}\n\t\treturn &flowPlan{run: run, display: display, fallback: manual}, nil\n\t}\n\n\treturn &flowPlan{run: run, userAction: manual}, nil\n}\n\n// beginDevice prepares the device authorization flow. It requests a device code\n// up front (so the code can be displayed) and selects a display channel:\n// URL elicitation, then form elicitation, then a tool-response message.\nfunc (m *Manager) beginDevice(prompter Prompter) (*flowPlan, error) {\n\toc := m.oauth2Config(\"\")\n\n\tctx, cancel := context.WithTimeout(context.Background(), deviceAuthTimeout)\n\tdefer cancel()\n\tda, err := oc.DeviceAuth(ctx)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"requesting device code: %w\", err)\n\t}\n\n\trun := func(ctx context.Context) (*oauth2.Token, error) {\n\t\ttok, err := oc.DeviceAccessToken(ctx, da)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"awaiting device authorization: %w\", err)\n\t\t}\n\t\treturn tok, nil\n\t}\n\n\t// As with PKCE, the manual instructions double as the runtime fallback, so\n\t// build them once and reuse for both display plans and the last resort.\n\tmanual := &UserAction{\n\t\tURL:      da.VerificationURI,\n\t\tUserCode: da.UserCode,\n\t\tMessage: fmt.Sprintf(\n\t\t\t\"%s\\n\\nAfter authorizing, retry your request.\\n\\n%s\",\n\t\t\tdeviceInstruction(da), securityAdvisory,","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/internal/oauth/flow.go#L148-L184","documentation":"The initial device-authorization request (oc.DeviceAuth) failed, so the device flow cannot even be prepared. Bounded by the 30-second deviceAuthTimeout, it fails on network errors, non-200 responses from the device code endpoint, or GitHub rejecting the app (e.g. client credentials wrong, or the endpoint unreachable on older GitHub Enterprise Server). Because this happens during flow preparation, the caller gets the error immediately rather than at run time.","triggerScenarios":"oc.DeviceAuth(ctx) at internal/oauth/flow.go:164 errors: POST to https://github.com/login/device/code returns 401/403 (bad client_id/secret), the device endpoint is blocked by a firewall/proxy, GHES older than the device-flow support returns 404, or the 30s timeout expires on a stalled connection.","commonSituations":"Firewalled environments blocking github.com login endpoints while allowing api.github.com; OAuth app client secret rotated but the server config still has the old one; GHES pre-3.x without device flow; PKCE was unavailable (headless, random port) and device flow is the sole remaining path, so its failure surfaces directly.","solutions":["Verify reachability of the device endpoint: curl -X POST https://github.com/login/device/code from the same host","Confirm the OAuth app's client ID/secret are current (rotated secrets are the classic 401 here)","On GHES, upgrade to a version supporting the device flow or use a PAT/app installation auth instead","If PKCE also failed, fix the primary cause (see 115/116) rather than relying on device flow"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"func deviceEndpointReachable() bool {\n    c := &http.Client{Timeout: 5 * time.Second}\n    resp, err := c.Post(\"https://github.com/login/device/code\", \"application/json\", nil)\n    return err == nil && resp != nil // any status (even 4xx) proves reachability\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"requesting device code\") {\n    // 401 -> client credentials rotated; network text -> egress/proxy; 404 on GHES -> no device flow\n}","preventionTips":["Allow egress to github.com/login/* (not just api.github.com) in firewalled environments","Rotate and deploy client secrets atomically with the config referencing them","On GHES, verify device-flow support before offering it as the fallback auth path"],"tags":["oauth","device-flow","network","configuration","github-enterprise"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}