hashicorp/terraform · error

new container client

Error message

new container client: %v

What it means

Thrown by getContainersClient when containers.NewWithBaseUri(baseUri) fails. Mirror of error 141 for the containers client (used by Workspaces() to enumerate state files). The baseUri validation rejects non-absolute or malformed URLs.

Solutions

  1. Verify storage_account_name is lowercase alphanumerics, 3-24 chars.
  2. Check metadata_host / environment with TF_LOG=DEBUG.
  3. Toggle lookup_blob_endpoint to control naive-vs-learned URL.
  4. Run `terraform workspace list` again after fixing the underlying URL.
Defensive patterns

Strategy: validation

Validate before calling

// Reuse the same base-URL validation as for the blob client.
func validateContainerBaseURL(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 container base url %q: %w", base, err) }
    if u.Scheme != "https" || u.Host == "" { return fmt.Errorf("container base url must be https with a host: %q", base) }
    return nil
}

Prevention

When it happens

Trigger: First call to getContainersClient (typically from Workspaces, i.e. `terraform workspace list`). The constructed base URL is malformed: custom environment with empty/invalid storage domain suffix, private DNS blob endpoint returning an invalid URL, or storage_account_name with illegal characters.

Common situations: Sovereign cloud misconfigured; metadata_host returning wrong primaryEndpoints.blob; storage_account_name with underscores/uppercase/trailing whitespace.

Related errors


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

Appendix: source

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

	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
		}
	}

	containersClient, err := containers.NewWithBaseUri(baseUri)
	if err != nil {
		return nil, fmt.Errorf("new container client: %v", err)
	}

	switch {
	case c.sasToken != "":
		log.Printf("[DEBUG] Building the Container Client from a SAS Token")
		c.configureClient(containersClient.Client, nil)
		containersClient.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 containersClient, nil

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

View on GitHub (pinned to d32a084675)