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

Failed to create PAT

Error message

Failed to create PAT

What it means

This Trace2Exception is thrown by CreatePersonalAccessTokenAsync when the Azure DevOps REST API call fails to produce a Personal Access Token. It is the final fallback after all failure paths have already attempted to surface a specific error message; reaching it means no PAT was generated and no more specific error was extracted from the HTTP responses. The caller cannot proceed with Azure Repos authentication without a PAT.

Solutions

  1. Retry the operation; HTTP 500s from the location/identity services are often transient Azure DevOps issues
  2. Check Azure DevOps service health/status for your region
  3. Verify the organization URL and access token passed in are valid and not expired
  4. Inspect Trace2 logs for the more specific 'Failed to create PAT: {errorMessage}' variant emitted earlier for the actual API error
  5. Update Git Credential Manager to the latest version in case of API contract changes

Example fix

// before
var pat = await AzureDevOpsRestApi.CreatePersonalAccessTokenAsync(...);
// after
try {
    var pat = await AzureDevOpsRestApi.CreatePersonalAccessTokenAsync(...);
} catch (Trace2Exception ex) when (IsTransient(ex)) {
    // retry with backoff or surface actionable guidance
}
Defensive patterns

Strategy: retry

Validate before calling

// C#
if (!uri.Host.Equals("dev.azure.com", StringComparison.OrdinalIgnoreCase) && !uri.Host.EndsWith(".visualstudio.com", StringComparison.OrdinalIgnoreCase))
    throw new ArgumentException("Not a valid Azure DevOps organization URL");

Try / catch

try {
    pat = await AzureDevOpsRestApi.CreatePersonalAccessTokenAsync(orgUri, accessToken, ...);
} catch (Trace2Exception ex) {
    _log.Error(ex, "PAT creation failed");
    throw new InvalidOperationException("Could not create PAT; check Azure DevOps service health and credentials", ex);
}

Prevention

When it happens

Trigger: Calling CreatePersonalAccessTokenAsync when the location service and/or identity service respond in a way that does not yield a PAT (e.g. HTTP 500 responses from either service where no errorMessage could be extracted, or an unexpected response shape).

Common situations: Azure DevOps service outages or degraded instances returning 5xx; organizational issues where the identity service rejects token creation; transient network errors producing non-success responses without a parseable error body.

Related errors


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

Appendix: source

Thrown at src/Microsoft.AzureRepos/AzureDevOpsRestApi.cs:151

                {
                    if (response.IsSuccessStatusCode)
                    {
                        if (TryGetFirstJsonStringField(responseText, "token", out string token))
                        {
                            return token;
                        }
                    }
                    else
                    {
                        if (TryGetFirstJsonStringField(responseText, "message", out string errorMessage))
                        {
                            throw new Trace2Exception(_context.Trace2, $"Failed to create PAT: {errorMessage}");
                        }
                    }
                }
            }

            throw new Trace2Exception(_context.Trace2, "Failed to create PAT");
        }

        #region Private Methods

        private async Task<Uri> GetIdentityServiceUriAsync(Uri organizationUri, string accessToken)
        {
            const string locationServicePath = "_apis/ServiceDefinitions/LocationService2/951917AC-A960-4999-8464-E3F0AA25B381";
            const string locationServiceQuery = "api-version=1.0";

            Uri requestUri = new UriBuilder(organizationUri)
            {
                Path = UriHelpers.CombinePath(organizationUri.AbsolutePath, locationServicePath),
                Query = locationServiceQuery,
            }.Uri;

            _context.Trace.WriteLine($"HTTP: GET {requestUri}");
            using (HttpRequestMessage request = CreateRequestMessage(HttpMethod.Get, requestUri, bearerToken: accessToken))
            using (HttpResponseMessage response = await HttpClient.SendAsync(request))

View on GitHub (pinned to e8ce762cd0)