argoproj/argo-workflows · error

unable to create Azure Blob Container client for %s: %w

Error message

unable to create Azure Blob Container client for %s: %w

What it means

Save builds an Azure container client (newAzureContainerClient) before uploading. If constructing the client fails — typically because credentials or the endpoint/account are missing or malformed — the error is wrapped with this message naming the blob.

Source

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

	return response.Body, nil
}

// Save saves an artifact to Azure Blob Storage
func (azblobDriver *ArtifactDriver) Save(ctx context.Context, path string, outputArtifact *wfv1.Artifact) error {
	logger := logging.RequireLoggerFromContext(ctx)
	logger.WithField("endpoint", outputArtifact.Azure.Endpoint).
		WithField("container", outputArtifact.Azure.Container).
		WithField("blob", outputArtifact.Azure.Blob).
		Info(ctx, "Saving to Azure Blob Storage")

	isDir, err := file.IsDirectory(path)
	if err != nil {
		return fmt.Errorf("failed to test if %s is a directory: %w", path, err)
	}

	containerClient, err := azblobDriver.newAzureContainerClient(ctx)
	if err != nil {
		return fmt.Errorf("unable to create Azure Blob Container client for %s: %w", outputArtifact.Azure.Blob, err)
	}

	if isDir {
		err := PutDirectory(ctx, containerClient, outputArtifact.Azure.Blob, path)
		if err != nil {
			return fmt.Errorf("unable to upload directory %s to Azure: %w", path, err)
		}
	} else {
		err := PutFile(ctx, containerClient, outputArtifact.Azure.Blob, path)
		if err != nil {
			return fmt.Errorf("unable to upload file %s to Azure: %w", path, err)
		}
	}

	return nil
}

// SaveStream saves an artifact from an io.Reader to Azure Blob Storage

View on GitHub (pinned to 35bff19146)

Solutions

  1. Check artifactRepository config (workflow-controller-configmap) has correct azure endpoint, container, and accessKeySecret reference.
  2. Verify the referenced Secret exists in the controller/workflow namespace and contains a valid account key.
  3. Confirm endpoint format: https://<account>.blob.core.windows.net (or correct sovereign/ADLS endpoint).
  4. Regenerate the key if the storage account key was rotated.
  5. Test credentials manually: az storage container list with the same key.

Example fix

// before: configmap
artifactRepository:
  azure:
    endpoint: https://mystorageaccount.blob.core.windows.net
    container: my-container
// after: add secret ref
artifactRepository:
  azure:
    endpoint: https://mystorageaccount.blob.core.windows.net
    container: my-container
    accessKeySecret:
      name: azure-credentials
      key: accessKey
Defensive patterns

Strategy: validation

Validate before calling

if os.Getenv("AZURE_STORAGE_ACCOUNT") == "" || os.Getenv("AZURE_STORAGE_ACCESS_KEY") == "" {
  return errors.New("azure credentials not configured")
}
if _, err := url.Parse(endpoint); err != nil {
  return fmt.Errorf("invalid azure endpoint: %w", err)
}

Type guard

func azureConfigValid(cfg *AzureArtifactRepository) bool {
  return cfg != nil && cfg.Endpoint != "" && cfg.Container != "" &&
    cfg.AccessKeySecret.Name != "" && cfg.AccessKeySecret.Key != ""
}

Try / catch

err := driver.Save(ctx, path, artifact)
if err != nil && strings.Contains(err.Error(), "unable to create Azure Blob Container client") {
  // check configmap artifactRepository + secret before retrying
  return fmt.Errorf("azure artifact config invalid: %w", err)
}

Prevention

When it happens

Trigger: Save/SaveStream when the artifact repository config lacks accessKey/connection string, the AZURE_STORAGE_ACCOUNT/KEY env or secret is absent/invalid, or the endpoint URL cannot be parsed.

Common situations: artifactRepository azure block missing accessKey Secret ref; wrong secret key name; typo in account or endpoint (e.g. missing https:// or core.windows.net suffix); k8s secret in wrong namespace.

Related errors


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