{"record":{"id":"def9ae779dbd6a90","repo":"hashicorp/terraform","slug":"new-blob-client-v","errorCode":null,"errorMessage":"new blob client: %v","messagePattern":"new blob client: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/azure/api_client.go","lineNumber":148,"sourceCode":"\n\tvar baseUri string\n\tif c.accountDetail != nil {\n\t\t// Use the actual blob endpoint if available\n\t\tpBaseUri, err := c.accountDetail.DataPlaneEndpoint(EndpointTypeBlob)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tbaseUri = *pBaseUri\n\t} else {\n\t\tbaseUri, err = naiveStorageAccountBlobBaseURL(c.environment, c.storageAccountName)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tblobsClient, err := blobs.NewWithBaseUri(baseUri)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"new blob client: %v\", err)\n\t}\n\n\tswitch {\n\tcase c.sasToken != \"\":\n\t\tlog.Printf(\"[DEBUG] Building the Blob Client from a SAS Token\")\n\t\tc.configureClient(blobsClient.Client, nil)\n\t\tblobsClient.Client.AppendRequestMiddleware(func(r *http.Request) (*http.Request, error) {\n\t\t\tif r.URL.RawQuery == \"\" {\n\t\t\t\tr.URL.RawQuery = c.sasToken\n\t\t\t} else if !strings.Contains(r.URL.RawQuery, c.sasToken) {\n\t\t\t\tr.URL.RawQuery = fmt.Sprintf(\"%s&%s\", r.URL.RawQuery, c.sasToken)\n\t\t\t}\n\t\t\treturn r, nil\n\t\t})\n\t\treturn blobsClient, nil\n\n\tcase c.accessKey != \"\":\n\t\tlog.Printf(\"[DEBUG] Building the Blob Client from an Access Key\")","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/azure/api_client.go#L130-L166","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify storage_account_name is all-lowercase, 3-24 chars, alphanumerics only.","If using a custom environment, check metadata_host returns the correct blob endpoint via TF_LOG=DEBUG.","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.","Re-run with TF_LOG=DEBUG to print the actual baseUri being passed to NewWithBaseUri."],"exampleFix":"// before\nterraform {\n  backend \"azurerm\" {\n    storage_account_name = \"MyAccount\"\n  }\n}\n// after\nterraform {\n  backend \"azurerm\" {\n    storage_account_name = \"myaccount\"\n  }\n}","handlingStrategy":"validation","validationCode":"// Validate the blob base URL is parseable before constructing the giovanni client.\nfunc validateBlobBaseURL(env environments.Environment, accountName string) error {\n    base, err := naiveStorageAccountBlobBaseURL(env, accountName)\n    if err != nil { return err }\n    u, err := url.Parse(base)\n    if err != nil { return fmt.Errorf(\"invalid blob base url %q: %w\", base, err) }\n    if u.Scheme != \"https\" || u.Host == \"\" { return fmt.Errorf(\"blob base url must be https with a host: %q\", base) }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Lowercase and validate storage_account_name at config-load time (regex ^[a-z0-9]{3,24}$).","When using a custom environment, smoke-test the blob endpoint with curl before terraform init.","Run with TF_LOG=DEBUG on first use of a new environment to print the resolved baseUri."],"tags":["azure","blob","url-parsing","configuration","terraform-backend"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}