Back to Azure Sdk For

Troubleshoot Azure Container Registry client library issues

sdk/containerregistry/Azure.Containers.ContainerRegistry/TROUBLESHOOTING.md

2019-05-16T16-528.9 KB
Original Source

Troubleshoot Azure Container Registry client library issues

This troubleshooting guide contains instructions to diagnose frequently encountered issues while using the Azure Container Registry client library for .NET.

Table of contents

General troubleshooting

All container registry service operations will throw a RequestFailedException on failure.

When you interact with the library, errors returned by the service correspond to the same HTTP status codes returned for REST API requests.

Here's an example of how to catch an exception using synchronous method

C#
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));

// Create a ContainerRepository class for an invalid repository
string fakeRepositoryName = "doesnotexist";
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
ContainerRepository repository = client.GetRepository(fakeRepositoryName);

try
{
    repository.GetProperties();
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
    Console.WriteLine("Repository wasn't found.");
    Console.WriteLine($"Service error: {ex.Message}.");
}

Here's an example of how to catch an exception using asynchronous method:

C#
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));

// Create a ContainerRepository class for an invalid repository
string fakeRepositoryName = "doesnotexist";
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential());
ContainerRepository repository = client.GetRepository(fakeRepositoryName);

try
{
    await repository.GetPropertiesAsync();
}
catch (RequestFailedException ex) when (ex.Status == 404)
{
    Console.WriteLine("Repository wasn't found.");
    Console.WriteLine($"Service error: {ex.Message}.");
}

Enable client logging

To troubleshoot issues with the library, first enable logging to monitor the behavior of the application. The errors and warnings in the logs generally provide useful insights into what went wrong and sometimes include corrective actions to fix issues.

This library uses the standard logging library. Basic information about HTTP sessions, such as URLs and headers, is logged at the INFO level.

The simplest way to see the logs is to enable console logging. To create an Azure SDK log listener that outputs messages to the console, use the AzureEventSourceListener.CreateConsoleLogger method:

csharp
using Azure.Core.Diagnostics;

// set up a listener to monitor logged events
using AzureEventSourceListener listener = AzureEventSourceListener.CreateConsoleLogger();

Enable content logging

By default only URI and headers are logged. To enable content logging, set the Diagnostics.IsLoggingContentEnabled client option.

c#
ContainerRegistryClientOptions options = new ContainerRegistryClientOptions()
{
    Diagnostics =
    {
        IsLoggingContentEnabled = true
    }
};

Logging redacted headers and query parameters

Some sensitive headers and query parameters are not logged by default and are displayed as "REDACTED", to include them in logs use the Diagnostics.LoggedHeaderNames and Diagnostics.LoggedQueryParameters client options.

c#
ContainerRegistryClientOptions options = new ContainerRegistryClientOptions()
{
    Diagnostics =
    {
        LoggedHeaderNames = { "x-ms-request-id" },
        LoggedQueryParameters = { "api-version" }
    }
};

You can also disable redaction completely by adding a "*" to collections mentioned above.

c#
ContainerRegistryClientOptions options = new ContainerRegistryClientOptions()
{
    Diagnostics =
    {
        LoggedHeaderNames = { "*" },
        LoggedQueryParameters = { "*" }
    }
};

To learn about other logging mechanisms, see Azure SDK diagnostics.

Troubleshooting authentication issues

Azure Container Registry supports Azure Active Directory authentication. To provide a valid credential, you can use the Azure.Identity package. For more information on getting started, see the Azure Container Registry library's README. For details on the credential types supported in Azure.Identity, see the Azure Identity library's documentation.

Here are the authentication exceptions and ways to handle it:

AuthenticationFailedException

Exceptions arising from authentication errors can be raised on any service client method that makes a request to the service. This is because the token is requested from the credential on the first call to the service and on any subsequent requests to the service that need to refresh the token.

To distinguish these failures from failures in the service client, Azure Identity classes raise the AuthenticationFailedException with details describing the source of the error in the exception message and possibly the error message. Depending on the application, these errors may or may not be recoverable.

c#
using Azure.Identity;
using Azure.Containers.ContainerRegistry;

// Create a ContainerRegistryClient using the DefaultAzureCredential
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("REGISTRY_ENDPOINT"));

string repositoryName = "RepositoryName";
ContainerRegistryClient client = new ContainerRegistryClient(endpoint, new DefaultAzureCredential(),
    new ContainerRegistryClientOptions()
    {
        Audience = ContainerRegistryAudience.AzureResourceManagerPublicCloud
    });
ContainerRepository repository = client.GetRepository(repositoryName);

try
{
    repository.GetProperties();
}
catch (AuthenticationFailedException e)
{
    Console.WriteLine($"Authentication Failed. {e.Message}");
}

CredentialUnavailableException

The CredentialUnavailableExcpetion is a special exception type derived from AuthenticationFailedException. This exception type is used to indicate that the credential can’t authenticate in the current environment, due to lack of required configuration or setup. This exception is also used as a signal to chained credential types, such as DefaultAzureCredential and ChainedTokenCredential, that the chained credential should continue to try other credential types later in the chain.

Permission Issues

Calls to service clients resulting in RequestFailedException with a StatusCode of 401 or 403 often indicate the caller doesn't have sufficient permissions for the specified API. Check the service documentation to determine which RBAC roles are needed for the specific request, and ensure the authenticated user or service principal have been granted the appropriate roles on the resource.

For more help with troubleshooting authentication errors, see the Azure Identity client library troubleshooting guide.

Service errors

When working with ContainerRegistryContentClient, you may get an RequestFailedException exception with message containing additional information and Docker error code.

Getting BLOB_UPLOAD_INVALID

In rare cases, a transient error (such as connection reset) can happen during blob upload which may lead to a RequestFailedException with a 404 status code being thrown with message similar to {"errors":[{"code":"BLOB_UPLOAD_INVALID","message":"blob upload invalid"}]}, and resulting in a failed upload. In this case, upload should to be restarted from the beginning.

The following code sample illustrates how you can catch this exception.

C#
try
{
    BinaryData blob = BinaryData.FromString("Sample blob.");
    UploadRegistryBlobResult uploadResult = await client.UploadBlobAsync(blob);
}
catch (RequestFailedException ex) when (ex.Status == 404 && ex.ErrorCode == "BLOB_UPLOAD_INVALID")
{
    Console.WriteLine("Blob upload failed. Please retry.");
    Console.WriteLine($"Service error: {ex.Message}");
}