argoproj/argo-workflows · error

unable to create Azure Blob Container client: %w

Error message

unable to create Azure Blob Container client: %w

What it means

Load wraps any failure from newAzureContainerClient (endpoint parse, credential creation, missing account key, shared-key failure) with this message while downloading an Azure artifact. It is an aggregator: the interesting cause is always after ': %w'.

Source

Thrown at workflow/artifacts/azure/azure.go:117

// isSASAccountKey determines whether the account key provided is a SAS token instead of a
// storage account key. A SAS token is a string of query parameters that is appended to the
// URL of the storage account. This function looks for the presence of a query parameter in
// the string and returns true if found.
func isSASAccountKey(accountKey string) bool {
	re := regexp.MustCompile(`(\?|\&)([^=]+)\=([^&]+)`)
	return re.MatchString(accountKey)
}

// Load downloads artifacts from Azure Blob Storage
func (azblobDriver *ArtifactDriver) Load(ctx context.Context, artifact *wfv1.Artifact, path string) error {
	logger := logging.RequireLoggerFromContext(ctx)
	logger.WithField("endpoint", artifact.Azure.Endpoint).
		WithField("container", artifact.Azure.Container).
		WithField("blob", artifact.Azure.Blob).
		Info(ctx, "Downloading from Azure Blob Storage")
	containerClient, err := azblobDriver.newAzureContainerClient(ctx)
	if err != nil {
		return fmt.Errorf("unable to create Azure Blob Container client: %w", err)
	}

	// Assume we're not downloading a directory and try to download as a file, since this is
	// the most common case and we don't want the penalty of listing the blobs before we
	// download (to determine if it's a directory instead of a single file). If we get a
	// BlobNotFound error, then check if it's a directory and process accordingly. If the account
	// has HNS enabled (ADLS Gen 2), then there's an edge case with using the blob API to
	// access. The directory will be returned as an empty file, so check for that as well.
	var isEmptyFile bool
	origErr := DownloadFile(ctx, containerClient, artifact.Azure.Blob, path)
	if origErr == nil {
		fileInfo, lstatErr := os.Lstat(path)
		if lstatErr != nil {
			return fmt.Errorf("unable to retrieve stats for downloaded file %s: %w", path, lstatErr)
		}

		// Empty file means it could be an ADLS Gen 2 account and we downloaded the
		// directory as an empty file -- we'll check below. If it's a non-empty file,

View on GitHub (pinned to 35bff19146)

Solutions

  1. Read the wrapped cause in the message and fix the underlying configuration (see endpoint/credential/account-key errors).
  2. Validate the azure artifactRepository configmap and referenced secret before submitting workflows.
  3. If using SDK creds, confirm the executor pod has workload identity annotations/labels attached.
Defensive patterns

Strategy: try-catch

Validate before calling

// validate azure config once before submitting:
// endpoint parses as URL AND (useSDKCreds true with identity bound OR accountKeySecret present)

Try / catch

err := driver.Load(ctx, artifact, path)
if err != nil {
	if strings.Contains(err.Error(), "unable to create Azure Blob Container client") {
		return fmt.Errorf("fix azure storage config (endpoint/credentials/accountKey): %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: Any of errors 403–407 occurring during a Load call: bad endpoint URL, no usable SDK credential, empty accountKey with useSDKCreds false, invalid shared key, or undeterminable account name.

Common situations: First artifact download of a workflow fails because the artifactRepository azure config secret is missing fields or the pod lacks identity bindings.

Related errors


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/c560a749d14a9625. Report an issue: GitHub.