git-ecosystem/git-credential-manager · error · Trace2Exception

Unencrypted HTTP is not recommended for Bitbucket.org…

Error message

Unencrypted HTTP is not recommended for Bitbucket.org. Ensure the repository remote URL is using HTTPS or see https://aka.ms/gcm/unsafe-remotes about how to allow unsafe remotes.

What it means

BitbucketHostProvider.GetCredentialAsync refuses to send credentials over unencrypted HTTP to bitbucket.org. If AllowUnsafeRemotes is disabled (default) and the request targets http://bitbucket.org, a Trace2Exception is thrown advising HTTPS or opting into unsafe remotes. This protects tokens from plaintext transmission.

Solutions

  1. Change the remote to HTTPS: git remote set-url origin https://bitbucket.org/user/repo.git
  2. If truly required, opt in via `git config --global credential.allowUnsafeRemotes true` (see https://aka.ms/gcm/unsafe-remotes)
  3. Update documentation/scripts/CI that clone from the http:// URL

Example fix

// before
url = "http://bitbucket.org/user/repo.git";
// after
url = "https://bitbucket.org/user/repo.git";
Defensive patterns

Strategy: validation

Validate before calling

var uri = new Uri(remoteUrl);
bool unsafeBitbucket = uri.Scheme == Uri.UriSchemeHttp && uri.Host.Equals("bitbucket.org", StringComparison.OrdinalIgnoreCase);
if (unsafeBitbucket && !allowUnsafeRemotes) throw new InvalidOperationException("Switch remote to HTTPS");

Type guard

bool IsHttpsRemote(Uri u) => u.Scheme == Uri.UriSchemeHttps;

Try / catch

try { await provider.GetCredentialAsync(input); }
catch (Trace2Exception ex) when (ex.Message.Contains("Unencrypted HTTP")) { /* rewrite remote to https and retry */ }

Prevention

When it happens

Trigger: git remote URL uses http:// for bitbucket.org (e.g. http://bitbucket.org/user/repo.git) while GCM_BITBUCKET_DEVSETTINGS / AllowUnsafeRemotes is false (default).

Common situations: Cloning with http:// by mistake; internal mirrors rewriting URLs to http; old scripts using http endpoints against bitbucket.org.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of git-ecosystem/git-credential-manager@e8ce762cd0 (2026-09-11). Data as JSON: /api/errors/58bb91a1f9d1613f. Report an issue: GitHub.

Appendix: source

Thrown at src/Atlassian.Bitbucket/BitbucketHostProvider.cs:94

                return false;
            }

            // Identify Bitbucket on-prem instances from the HTTP response using the Atlassian specific header X-AREQUESTID
            var supported = response.Headers.Contains("X-AREQUESTID");

            _context.Trace.WriteLine($"Host is{(supported ? null : "n't")} supported as Bitbucket");

            return supported;
        }

        public async Task<GitResponse> GetCredentialAsync(GitRequest request)
        {
            // We should not allow unencrypted communication and should inform the user
            if (!_context.Settings.AllowUnsafeRemotes &&
                StringComparer.OrdinalIgnoreCase.Equals(request.Protocol, "http") &&
                BitbucketHelper.IsBitbucketOrg(request))
            {
                throw new Trace2Exception(_context.Trace2,
                    "Unencrypted HTTP is not recommended for Bitbucket.org. " +
                    "Ensure the repository remote URL is using HTTPS " +
                    $"or see {Constants.HelpUrls.GcmUnsafeRemotes} about how to allow unsafe remotes.");
            }

            var authModes = await GetSupportedAuthenticationModesAsync(request);

            ICredential credential = await GetStoredCredentials(request, authModes) ??
                                     await GetRefreshedCredentials(request, authModes);
            return new GitResponse(credential);
        }

        private async Task<ICredential> GetStoredCredentials(GitRequest request, AuthenticationModes authModes)
        {
            if (_context.Settings.TryGetSetting(BitbucketConstants.EnvironmentVariables.AlwaysRefreshCredentials,
                Constants.GitConfiguration.Credential.SectionName, BitbucketConstants.GitConfiguration.Credential.AlwaysRefreshCredentials,
                out string alwaysRefreshCredentials) && alwaysRefreshCredentials.ToBooleanyOrDefault(false))
            {

View on GitHub (pinned to e8ce762cd0)