hashicorp/terraform · error

new shared key authorizer

Error message

new shared key authorizer: %v

What it means

Thrown by getBlobClient on the c.accessKey != "" branch when auth.NewSharedKeyAuthorizer(storageAccountName, accessKey, auth.SharedKey) returns an error. The shared-key authorizer base64-decodes the key and prepares HMAC-SHA256 signing; failure means the key value is malformed or the account name is unusable for signing.

Solutions

  1. Re-fetch the key via `az storage account keys list -g <rg> -n <acct>` and paste the value verbatim.
  2. Trim any whitespace or surrounding quotes around access_key in the backend block / env var.
  3. Confirm storage_account_name is set and matches the key.
  4. Switch to use_azuread_auth = true to bypass shared-key signing entirely.

Example fix

// before
access_key = "  <pastewith newlines>  "
// after
access_key = "<base64-value-with-no-whitespace>"
Defensive patterns

Strategy: validation

Validate before calling

// Validate the access key is well-formed base64 before passing to NewSharedKeyAuthorizer.
func validateAccessKey(account, key string) error {
    if account == "" { return fmt.Errorf("storage_account_name is empty") }
    k := strings.TrimSpace(key)
    if k == "" { return fmt.Errorf("access_key is empty after trimming whitespace") }
    if _, err := base64.StdEncoding.DecodeString(k); err != nil {
        return fmt.Errorf("access_key is not valid base64: %w", err)
    }
    return nil
}

Prevention

When it happens

Trigger: access_key is set in the backend config; the value cannot be base64-decoded (extra whitespace, JSON quotes, wrong field pasted, truncated), or storage_account_name is empty/contains characters that break the canonical string-to-sign.

Common situations: Operator copy-pasted the key from the portal with leading/trailing whitespace or surrounding quotes; pasted the key ID/name (e.g. key1) instead of the key value; environment variable interpolation produced an empty string; key truncated during transfer.

Related errors


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

Appendix: source

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

	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")
		authorizer, err := auth.NewSharedKeyAuthorizer(c.storageAccountName, c.accessKey, auth.SharedKey)
		if err != nil {
			return nil, fmt.Errorf("new shared key authorizer: %v", err)
		}
		c.configureClient(blobsClient.Client, authorizer)
		return blobsClient, nil

	case c.azureAdStorageAuth != nil:
		log.Printf("[DEBUG] Building the Blob Client from AAD auth")
		c.configureClient(blobsClient.Client, c.azureAdStorageAuth)
		return blobsClient, nil

	default:
		// Neither shared access key, sas token, or AAD Auth were specified so we have to call the management plane API to get the key.
		log.Printf("[DEBUG] Building the Blob Client from an Access Key (key is listed using client credentials)")
		key, err := c.accountDetail.AccountKey(ctx, c.storageAccountsClient)
		if err != nil {
			return nil, fmt.Errorf("retrieving key for Storage Account %q: %s", c.storageAccountName, err)
		}
		authorizer, err := auth.NewSharedKeyAuthorizer(c.storageAccountName, *key, auth.SharedKey)
		if err != nil {

View on GitHub (pinned to d32a084675)