git-ecosystem/git-credential-manager · error · Trace2Exception
Unencrypted HTTP is not recommended for Azure Repos. Ensure…
Error message
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. What it means
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.
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
Example fix
// before git remote set-url origin http://dev.azure.com/myorg/Proj/_git/repo // after git remote set-url origin https://dev.azure.com/myorg/Proj/_git/repo
Defensive patterns
Strategy: validation
Validate before calling
// C# / shell // git config --get remote.origin.url | grep -E '^http://' -> if match, rewrite to https git remote set-url origin $(git remote get-url origin | sed 's|^http://|https://|')
Try / catch
try {
await provider.GeneratePersonalAccessTokenAsync(input);
} catch (Trace2Exception ex) when (ex.Message.Contains("Unencrypted HTTP")) {
Console.Error.WriteLine("Remote uses http://. Switch to https:// or enable unsafe remotes per GCM docs.");
} Prevention
- 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
When it happens
Trigger: Calling GeneratePersonalAccessTokenAsync or GetEntraAccessTokenAsync for a GitRequest whose Protocol is 'http' (case-insensitive) while the azure.allowUnsafeRemotes (http.allowUnsafeRemotes-related) setting is not enabled.
Common situations: 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.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- Unencrypted HTTP is not recommended for Bitbucket.org…
- Unencrypted HTTP is not recommended for GitHub. Ensure the…
- Unencrypted HTTP is not recommended for GitLab. Ensure the…
- Failed to create PAT
- Host is not Azure DevOps.
AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11).
Data as JSON: /api/errors/d0d8c7e1f7c8594d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.AzureRepos/AzureReposHostProvider.cs:251
// Clear the authority cache in case this was the reason for failure
_authorityCache.EraseAuthority(orgName);
}
return Task.CompletedTask;
}
protected override void ReleaseManagedResources()
{
_azDevOps.Dispose();
base.ReleaseManagedResources();
}
private void ThrowIfUnsafeRemote(GitRequest request)
{
if (!_context.Settings.AllowUnsafeRemotes &&
StringComparer.OrdinalIgnoreCase.Equals(request.Protocol, "http"))
{
throw new Trace2Exception(_context.Trace2,
"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.");
}
}
private async Task<ICredential> GeneratePersonalAccessTokenAsync(GitRequest request)
{
ThrowIfDisposed();
ThrowIfUnsafeRemote(request);
Uri remoteUserUri = request.GetRemoteUri(includeUser: true);
Uri orgUri = UriHelpers.CreateOrganizationUri(remoteUserUri, out _);
// Determine the Entra authentication authority for this organization
_context.Trace.WriteLine("Determining Entra authentication authority...");
string authAuthority = await _azDevOps.GetAuthorityAsync(orgUri);
_context.Trace.WriteLine($"Authority is '{authAuthority}'.");View on GitHub (pinned to e8ce762cd0)