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

Only localhost is supported as a redirect URI.

Error message

Only localhost is supported as a redirect URI.

What it means

OAuth2SystemWebBrowser.UpdateRedirectUri rewrites the redirect URI to a loopback address with a free TCP port so the embedded system browser can intercept the authorization response. It throws ArgumentException because only loopback (localhost/127.0.0.1) redirect URIs can be intercepted locally.

Solutions

  1. Use a loopback redirect URI such as http://localhost/callback (port is optional; a free port is chosen automatically)
  2. Register http://localhost as an allowed redirect URI in your OAuth provider's app settings
  3. Use a different browser/flow (e.g. device code flow) when a non-loopback redirect is required

Example fix

// before
browser.UpdateRedirectUri(new Uri("https://myapp.example.com/callback"));
// after
browser.UpdateRedirectUri(new Uri("http://localhost/callback"));
Defensive patterns

Strategy: validation

Validate before calling

if (!redirectUri.IsLoopback) throw new ArgumentException("Browser flow requires a loopback redirect URI; use device code flow instead.", nameof(redirectUri));

Type guard

bool IsLoopbackRedirect(Uri u) => u.IsLoopback;

Try / catch

try { uri = browser.UpdateRedirectUri(uri); } catch (ArgumentException) { return await GetTokenByDeviceCodeAsync(client, scopes); }

Prevention

When it happens

Trigger: Calling UpdateRedirectUri with a Uri whose IsLoopback is false — e.g. https://myapp.example.com/callback, a public hostname, or a non-loopback IP.

Common situations: Registering an OAuth app with an https production redirect URI and reusing it in a desktop flow; copying a web-app redirect URI into the CLI config; misunderstanding that this browser implementation only supports local loopback interception.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Core/Authentication/OAuth/OAuth2SystemWebBrowser.cs:85

</script></body></html>";

        private readonly ISessionManager _sessionManager;
        private readonly OAuth2WebBrowserOptions _options;

        public OAuth2SystemWebBrowser(ISessionManager sessionManager, OAuth2WebBrowserOptions options)
        {
            EnsureArgument.NotNull(sessionManager, nameof(sessionManager));
            EnsureArgument.NotNull(options, nameof(options));

            _sessionManager = sessionManager;
            _options = options;
        }

        public Uri UpdateRedirectUri(Uri uri)
        {
            if (!uri.IsLoopback)
            {
                throw new ArgumentException("Only localhost is supported as a redirect URI.", nameof(uri));
            }

            // If a port has been specified use it, otherwise find a free one
            if (uri.IsDefaultPort)
            {
                int port = GetFreeTcpPort();
                return new UriBuilder(uri) {Port = port}.Uri;
            }

            return uri;
        }

        public async Task<IDictionary<string, string>> GetAuthenticationResponseAsync(
            Uri authorizationUri, Uri redirectUri, OAuth2ResponseMode responseMode, CancellationToken ct)
        {
            if (!redirectUri.IsLoopback)
            {
                throw new ArgumentException("Only localhost is supported as a redirect URI.", nameof(redirectUri));

View on GitHub (pinned to e8ce762cd0)