argoproj/argo-workflows · error

unable to parse Azure Blob Storage endpoint url %s: %w

Error message

unable to parse Azure Blob Storage endpoint url %s: %w

What it means

newAzureContainerClient parses the configured Azure Blob Storage endpoint with url.Parse before attaching the container name; a malformed endpoint string produces this wrapped error. It is the first failure point for every Azure artifact operation (Load, Save, streams, Delete, ListObjects).

Source

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

)

// ArtifactDriver is a driver for Azure Blob Storage
type ArtifactDriver struct {
	AccountKey  string
	Container   string
	Endpoint    string
	UseSDKCreds bool
}

var _ artifactscommon.ArtifactDriver = &ArtifactDriver{}

// newAzureContainerClient creates a new container.Client for interacting with the specified Azure Blob Storage container
// The container client is created with the default azblob.ClientOptions which does include retry behavior
// for failed requests.
func (azblobDriver *ArtifactDriver) newAzureContainerClient(ctx context.Context) (*container.Client, error) {
	containerURL, err := url.Parse(azblobDriver.Endpoint)
	if err != nil {
		return nil, fmt.Errorf("unable to parse Azure Blob Storage endpoint url %s: %w", azblobDriver.Endpoint, err)
	}
	// Append the container name to the URL path
	if len(containerURL.Path) == 0 || containerURL.Path[len(containerURL.Path)-1] != '/' {
		containerURL.Path += "/"
	}
	containerURL.Path += azblobDriver.Container

	if azblobDriver.UseSDKCreds {
		credential, credErr := azidentity.NewDefaultAzureCredential(nil)
		if credErr != nil {
			return nil, fmt.Errorf("unable to create default Azure credential: %w", credErr)
		}
		containerClient, clientErr := container.NewClient(containerURL.String(), credential, nil)
		return containerClient, clientErr
	}
	if azblobDriver.AccountKey == "" {
		return nil, fmt.Errorf("accountKey secret is required for Azure Blob Storage if useSDKCreds is false")
	}

View on GitHub (pinned to 35bff19146)

Solutions

  1. Set endpoint to a full valid URL such as https://<account>.blob.core.windows.net in the artifact storage configuration.
  2. Verify the k8s secret value has no stray quotes, whitespace, or newlines (kubectl get secret ... -o jsonpath and inspect).
  3. Check the error's wrapped cause to see the exact parse failure reported by url.Parse.

Example fix

// before — endpoint in secret
endpoint: myaccount.blob.core.windows.net
// after
endpoint: https://myaccount.blob.core.windows.net
Defensive patterns

Strategy: validation

Validate before calling

func validateAzureEndpoint(endpoint string) error {
	u, err := url.Parse(endpoint)
	if err != nil || u.Scheme == "" || u.Host == "" {
		return fmt.Errorf("azure endpoint must be a full URL like https://<account>.blob.core.windows.net, got %q", endpoint)
	}
	return nil
}

Try / catch

containerClient, err := driver.newAzureContainerClient(ctx)
if err != nil {
	var urlErr *url.Error
	if errors.As(err, &urlErr) { /* fix endpoint URL */ }
	return fmt.Errorf("azure artifact download failed: %w", err)
}

Prevention

When it happens

Trigger: azblobDriver.Endpoint is empty, contains spaces, lacks a scheme (e.g. 'myaccount.blob.core.windows.net' without https://), or is otherwise not a valid URL.

Common situations: Missing endpoint in the azure artifact storage config secret; truncated or quoted endpoint value in a k8s secret; using an Azurite/localhost endpoint with a typo.

Understand the failure class

Related errors


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