{"record":{"id":"c8a7ed9d712fd3f0","repo":"git-ecosystem/git-credential-manager","slug":"unencrypted-http-is-not-recommended-for-github-en","errorCode":null,"errorMessage":"Unencrypted HTTP is not recommended for GitHub. Ensure the repository remote URL is using HTTPS or see {Constants.HelpUrls.GcmUnsafeRemotes} about how to allow unsafe remotes.","messagePattern":"Unencrypted HTTP is not recommended for GitHub\\. Ensure the repository remote URL is using HTTPS or see (.+?) about how to allow unsafe remotes\\.","errorType":"exception","errorClass":"Trace2Exception","httpStatus":null,"severity":"error","filePath":"src/GitHub/GitHubHostProvider.cs","lineNumber":293,"sourceCode":"                _context.Trace.WriteLine(\"Credential was successfully erased.\");\n            }\n            else\n            {\n                _context.Trace.WriteLine(\"No credential was erased.\");\n            }\n\n            return Task.CompletedTask;\n        }\n\n        internal /* for testing purposes */  async Task<ICredential> GenerateCredentialAsync(Uri remoteUri, string userName)\n        {\n            ThrowIfDisposed();\n\n            // We should not allow unencrypted communication and should inform the user\n            if (!_context.Settings.AllowUnsafeRemotes &&\n                StringComparer.OrdinalIgnoreCase.Equals(remoteUri.Scheme, \"http\"))\n            {\n                throw new Trace2Exception(_context.Trace2,\n                    \"Unencrypted HTTP is not recommended for GitHub. \" +\n                    \"Ensure the repository remote URL is using HTTPS \" +\n                    $\"or see {Constants.HelpUrls.GcmUnsafeRemotes} about how to allow unsafe remotes.\");\n            }\n\n            string service = GetServiceName(remoteUri);\n\n            AuthenticationModes authModes = await GetSupportedAuthenticationModesAsync(remoteUri);\n\n            AuthenticationPromptResult promptResult = await _gitHubAuth.GetAuthenticationAsync(remoteUri, userName, authModes);\n\n            switch (promptResult.AuthenticationMode)\n            {\n                case AuthenticationModes.Basic:\n                    GitCredential patCredential = await GeneratePersonalAccessTokenAsync(remoteUri, promptResult.Credential);\n\n                    // HACK: Store the PAT immediately in case this PAT is not valid for SSO.\n                    // We don't know if this PAT is valid for SAML SSO and if it's not Git will fail","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/GitHub/GitHubHostProvider.cs#L275-L311","documentation":"GitHubHostProvider.GenerateCredentialAsync refuses to acquire credentials for an unencrypted http:// remote URL unless the user explicitly opts in, because credentials would be transmitted in clear text. It throws a Trace2Exception directing the user to switch the remote to HTTPS or read the GCM documentation on allowing unsafe remotes.","triggerScenarios":"git operation against a GitHub remote whose URL scheme is http:// while _context.Settings.AllowUnsafeRemotes is false (the default). Happens whenever GCM must generate a credential for such a remote.","commonSituations":"Cloning/pushing to 'http://github.com/...' by typo or company mirror proxy; legacy internal servers using plain HTTP; stale remote URLs left over from configuration migration.","solutions":["Change the remote to HTTPS: git remote set-url origin https://github.com/owner/repo.git","If plain HTTP is truly intended (e.g. internal proxy), allow it via config: git config --global credential.allowUnsafeRemotes true (or GCM_ALLOW_UNSAFE_REMETES env var GCM_ALLOW_UNSAFE_REMETES -> actually GCM_ALLOW_UNSAFE_REMETES documented as credential.allowUnsafeRemotes).","Verify the remote URL with 'git remote -v' and correct the scheme typo.","Use the documented help page (Constants.HelpUrls.GcmUnsafeRemotes) for environment-specific instructions."],"exampleFix":"// before\ngit remote set-url origin http://github.com/owner/repo.git\n\n// after\ngit remote set-url origin https://github.com/owner/repo.git\n// or, only if intentional:\ngit config --global credential.allowUnsafeRemotes true","handlingStrategy":"validation","validationCode":"var remoteUrl = new Uri(run(\"git remote get-url origin\"));\nif (remoteUrl.Scheme.Equals(\"http\", StringComparison.OrdinalIgnoreCase))\n{\n    // fix before invoking GCM\n    run($\"git remote set-url origin {new UriBuilder(remoteUrl) { Scheme = \"https\", Port = -1 }.Uri}\");\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    var cred = await provider.GenerateCredentialAsync(remoteUri, authModes);\n}\ncatch (Exception ex) when (ex.Message.Contains(\"Unencrypted HTTP\"))\n{\n    // rewrite remote to HTTPS or enable credential.allowUnsafeRemotes deliberately\n}","preventionTips":["Always use https:// remotes for GitHub","Audit 'git remote -v' in CI/bootstrap scripts for http:// URLs","Only set credential.allowUnsafeRemotes=true for internal proxies, never for github.com","Document the GcmUnsafeRemotes help URL for teams that must use plain HTTP"],"tags":["github","http","security","remote-url","tls"],"backgroundTag":"invalid-config-value","analyzedSha":"e8ce762cd04b4100ae637b5fbf39ef9d0a96561e","analyzedAt":"2026-09-11T17:15:08.753Z","contentChangedAt":"2026-09-11T17:15:08.753Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}