{"record":{"id":"d0d8c7e1f7c8594d","repo":"git-ecosystem/git-credential-manager","slug":"unencrypted-http-is-not-recommended-for-azure-repo","errorCode":null,"errorMessage":"Unencrypted HTTP is not recommended for Azure Repos. 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 Azure Repos\\. 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/Microsoft.AzureRepos/AzureReposHostProvider.cs","lineNumber":251,"sourceCode":"                // Clear the authority cache in case this was the reason for failure\n                _authorityCache.EraseAuthority(orgName);\n            }\n\n            return Task.CompletedTask;\n        }\n\n        protected override void ReleaseManagedResources()\n        {\n            _azDevOps.Dispose();\n            base.ReleaseManagedResources();\n        }\n\n        private void ThrowIfUnsafeRemote(GitRequest request)\n        {\n            if (!_context.Settings.AllowUnsafeRemotes &&\n                StringComparer.OrdinalIgnoreCase.Equals(request.Protocol, \"http\"))\n            {\n                throw new Trace2Exception(_context.Trace2,\n                    \"Unencrypted HTTP is not recommended for Azure Repos. \" +\n                    \"Ensure the repository remote URL is using HTTPS \" +\n                    $\"or see {Constants.HelpUrls.GcmUnsafeRemotes} about how to allow unsafe remotes.\");\n            }\n        }\n\n        private async Task<ICredential> GeneratePersonalAccessTokenAsync(GitRequest request)\n        {\n            ThrowIfDisposed();\n            ThrowIfUnsafeRemote(request);\n\n            Uri remoteUserUri = request.GetRemoteUri(includeUser: true);\n            Uri orgUri = UriHelpers.CreateOrganizationUri(remoteUserUri, out _);\n\n            // Determine the Entra authentication authority for this organization\n            _context.Trace.WriteLine(\"Determining Entra authentication authority...\");\n            string authAuthority = await _azDevOps.GetAuthorityAsync(orgUri);\n            _context.Trace.WriteLine($\"Authority is '{authAuthority}'.\");","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/Microsoft.AzureRepos/AzureReposHostProvider.cs#L233-L269","documentation":"ThrowIfUnsafeRemote guards against using unencrypted HTTP remotes with Azure Repos, since basic/token auth over HTTP would leak credentials. GCM refuses to authenticate against http:// Azure DevOps remotes unless the user explicitly opts in. The message points to a help page explaining how to allow unsafe remotes.","triggerScenarios":"Calling GeneratePersonalAccessTokenAsync or GetEntraAccessTokenAsync for a GitRequest whose Protocol is 'http' (case-insensitive) while the azure.allowUnsafeRemotes (http.allowUnsafeRemotes-related) setting is not enabled.","commonSituations":"Cloning/pushing with a remote URL like http://dev.azure.com/... or http://<org>.visualstudio.com/...; mirrors or internal proxies configured with http://; docs or tooling generating http URLs by mistake.","solutions":["Change the remote URL to HTTPS: git remote set-url origin https://dev.azure.com/<org>/<project>/_git/<repo>","If you genuinely must use HTTP (e.g. isolated test server), enable the unsafe-remotes option per the GcmUnsafeRemotes help URL","Audit all remotes: git remote -v and convert any http:// Azure DevOps remotes"],"exampleFix":"// before\ngit remote set-url origin http://dev.azure.com/myorg/Proj/_git/repo\n// after\ngit remote set-url origin https://dev.azure.com/myorg/Proj/_git/repo","handlingStrategy":"validation","validationCode":"// C# / shell\n// git config --get remote.origin.url | grep -E '^http://'   -> if match, rewrite to https\ngit remote set-url origin $(git remote get-url origin | sed 's|^http://|https://|')","typeGuard":null,"tryCatchPattern":"try {\n    await provider.GeneratePersonalAccessTokenAsync(input);\n} catch (Trace2Exception ex) when (ex.Message.Contains(\"Unencrypted HTTP\")) {\n    Console.Error.WriteLine(\"Remote uses http://. Switch to https:// or enable unsafe remotes per GCM docs.\");\n}","preventionTips":["Always clone with https:// URLs for Azure DevOps","Run git remote -v periodically and audit for http:// remotes","Never disable unsafe-remotes protection on developer machines","Use org policy/branch tooling to normalize remote URLs"],"tags":["azure-devops","http","security","remote-url"],"backgroundTag":"invalid-url","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"}