hashicorp/terraform · error

new blob client

Error message

new blob client: %v

What it means

Thrown by getBlobClient when blobs.NewWithBaseUri(baseUri) fails. The baseUri comes from either accountDetail.DataPlaneEndpoint(EndpointTypeBlob) or naiveStorageAccountBlobBaseURL(environment, accountName). The giovanni SDK validates the URL; this fires when baseUri is not a parseable absolute URL (missing scheme/host, illegal characters).

Solutions

  1. Verify storage_account_name is all-lowercase, 3-24 chars, alphanumerics only.
  2. If using a custom environment, check metadata_host returns the correct blob endpoint via TF_LOG=DEBUG.
  3. Toggle lookup_blob_endpoint: if naive URL is wrong, set it true to learn from ARM; if ARM returns wrong URL, set it false to use the environment-derived naive URL.
  4. Re-run with TF_LOG=DEBUG to print the actual baseUri being passed to NewWithBaseUri.

Example fix

// before
terraform {
  backend "azurerm" {
    storage_account_name = "MyAccount"
  }
}
// after
terraform {
  backend "azurerm" {
    storage_account_name = "myaccount"
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate the blob base URL is parseable before constructing the giovanni client.
func validateBlobBaseURL(env environments.Environment, accountName string) error {
    base, err := naiveStorageAccountBlobBaseURL(env, accountName)
    if err != nil { return err }
    u, err := url.Parse(base)
    if err != nil { return fmt.Errorf("invalid blob base url %q: %w", base, err) }
    if u.Scheme != "https" || u.Host == "" { return fmt.Errorf("blob base url must be https with a host: %q", base) }
    return nil
}

Prevention

When it happens

Trigger: First lazy call to getBlobClient (during StateMgr / Workspaces / Put). The constructed base URL is malformed: a custom environment whose storage domain suffix is empty or non-HTTP, a private DNS blob endpoint that returned an invalid URL, or a storage_account_name containing characters illegal in a hostname.

Common situations: Sovereign cloud (US Gov / China) misconfigured via environment name; metadata_host pointing at an endpoint that returns malformed primaryEndpoints.blob; storage_account_name with underscores, uppercase letters, or trailing whitespace; private DNS zone setup.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/def9ae779dbd6a90. Report an issue: GitHub.

Appendix: source

Thrown at internal/backend/remote-state/azure/api_client.go:148

	var baseUri string
	if c.accountDetail != nil {
		// Use the actual blob endpoint if available
		pBaseUri, err := c.accountDetail.DataPlaneEndpoint(EndpointTypeBlob)
		if err != nil {
			return nil, err
		}
		baseUri = *pBaseUri
	} else {
		baseUri, err = naiveStorageAccountBlobBaseURL(c.environment, c.storageAccountName)
		if err != nil {
			return nil, err
		}
	}

	blobsClient, err := blobs.NewWithBaseUri(baseUri)
	if err != nil {
		return nil, fmt.Errorf("new blob client: %v", err)
	}

	switch {
	case c.sasToken != "":
		log.Printf("[DEBUG] Building the Blob Client from a SAS Token")
		c.configureClient(blobsClient.Client, nil)
		blobsClient.Client.AppendRequestMiddleware(func(r *http.Request) (*http.Request, error) {
			if r.URL.RawQuery == "" {
				r.URL.RawQuery = c.sasToken
			} else if !strings.Contains(r.URL.RawQuery, c.sasToken) {
				r.URL.RawQuery = fmt.Sprintf("%s&%s", r.URL.RawQuery, c.sasToken)
			}
			return r, nil
		})
		return blobsClient, nil

	case c.accessKey != "":
		log.Printf("[DEBUG] Building the Blob Client from an Access Key")

View on GitHub (pinned to d32a084675)