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

Can only open HTTP/HTTPS URIs

Error message

Can only open HTTP/HTTPS URIs

What it means

SessionManager.OpenBrowser(Uri) only permits http and https schemes because the URL is passed to a shell-execute handler; other schemes (file:, ftp:, javascript:) are rejected with an ArgumentException. This is a security measure to prevent launching arbitrary handlers via crafted URIs.

Solutions

  1. Use the https:// (or http://) form of the URL before opening it in the browser
  2. Check uri.Scheme before calling OpenBrowser and show a user-facing error for non-HTTP URLs
  3. If a file needs to be shown, serve it over a local HTTP server instead of a file:// URI
  4. Investigate why a non-HTTP URL was produced (redirect chain, config value) and fix the source

Example fix

// before
sm.OpenBrowser(new Uri("file:///tmp/login.html")); // throws
// after
var uri = new Uri("https://github.com/login/device");
if (uri.Scheme == Uri.UriSchemeHttps)
    sm.OpenBrowser(uri);
Defensive patterns

Strategy: validation

Validate before calling

if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps)
    throw new ArgumentException($"Refusing to open non-HTTP URI in browser: {uri}");

Type guard

bool IsHttpUri(Uri u) => u.Scheme.Equals(Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) ||
    u.Scheme.Equals(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase);

Try / catch

try
{
    sm.OpenBrowser(uri);
}
catch (ArgumentException ex) when (ex.Message == "Can only open HTTP/HTTPS URIs")
{
    logger.LogError(ex, "Unexpected URI scheme {Scheme} from auth flow", uri.Scheme);
}

Prevention

When it happens

Trigger: Calling OpenBrowser with an absolute Uri whose Scheme is not http/https — e.g. file://, ftp://, ssh://, or a custom scheme.

Common situations: Redirect responses returning a non-HTTP URL, tests or tools passing local file:// links for a device-login page, or malicious/typoed redirect URLs from an identity provider.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at src/Core/ISessionManager.cs:67

            EnsureArgument.NotNull(trace, nameof(trace));
            EnsureArgument.NotNull(env, nameof(env));
            EnsureArgument.NotNull(fs, nameof(fs));

            Trace = trace;
            Environment = env;
            FileSystem = fs;
        }
        
        public abstract bool IsDesktopSession { get; }

        public virtual bool IsWebBrowserAvailable => IsDesktopSession;

        public void OpenBrowser(Uri uri)
        {
            if (!uri.Scheme.Equals(Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) &&
                !uri.Scheme.Equals(Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentException("Can only open HTTP/HTTPS URIs", nameof(uri));
            }

            // Important! Use AbsoluteUri to ensure that the URL is properly
            // escaped (e.g. spaces are converted to %20).
            // The 'shell execute' handler on some operating systems (e.g. macOS)
            // will try to validate the URL handed to it and if it sees any
            // unescaped characters it will decide that the rest of the query
            // parameters also need esacaping leading to double escaping!
            OpenBrowserInternal(uri.AbsoluteUri);
        }

        protected virtual void OpenBrowserInternal(string url)
        {
            Trace.WriteLine("Opening browser using framework shell-execute: " + url);
            var psi = new ProcessStartInfo(url) { UseShellExecute = true };
            Process.Start(psi);
        }
    }

View on GitHub (pinned to e8ce762cd0)