kubernetes/kops · error

unset AZURE_STORAGE_ACCOUNT; the storage account belongs in

Error message

unset AZURE_STORAGE_ACCOUNT; the storage account belongs in the URL:  azureblob://<account>/<container>/<key>

What it means

buildAzureBlobPath requires the storage account to come from the azureblob:// URL host, not from the AZURE_STORAGE_ACCOUNT environment variable. As written the guard fires when AZURE_STORAGE_ACCOUNT is set (the check is os.Getenv(...) != ""), instructing you to unset it and encode the account in the URL: azureblob://<account>/<container>/<key>.

Source

Thrown at util/pkg/vfs/context.go:571

	if err != nil {
		return nil, fmt.Errorf("invalid openstack cloud storage path: %q", p)
	}

	if u.Scheme != "swift" {
		return nil, fmt.Errorf("invalid openstack cloud storage path: %q", p)
	}

	bucket := strings.TrimSuffix(u.Host, "/")
	if bucket == "" {
		return nil, fmt.Errorf("invalid swift path: %q", p)
	}

	return NewSwiftPath(c, bucket, u.Path)
}

func (c *VFSContext) buildAzureBlobPath(p string) (*AzureBlobPath, error) {
	if os.Getenv("AZURE_STORAGE_ACCOUNT") != "" {
		return nil, fmt.Errorf("unset AZURE_STORAGE_ACCOUNT; the storage account belongs in the URL:  azureblob://<account>/<container>/<key>")
	}

	u, err := url.Parse(p)
	if err != nil {
		return nil, fmt.Errorf("failed to parse %q: %s", p, err)
	}

	if u.Scheme != "azureblob" {
		return nil, fmt.Errorf("invalid Azure Blob scheme: %q", p)
	}

	account := strings.TrimSuffix(u.Host, "/")
	if account == "" {
		return nil, fmt.Errorf("no storage account specified in %q; expected azureblob://<account>/<container>/<key>", p)
	}

	rest := strings.TrimPrefix(u.Path, "/")
	container, key, _ := strings.Cut(rest, "/")

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Unset the variable before running: `unset AZURE_STORAGE_ACCOUNT` (or `env -u AZURE_STORAGE_ACCOUNT kops ...`)
  2. Move the account name into the URL host: azureblob://<account>/<container>/<key>
  3. Audit CI/shell profiles for where AZURE_STORAGE_ACCOUNT is exported and remove it from that environment
  4. Note the check's message/condition read inverted relative to each other — if you expected the error only when the variable is unset, verify your kops version's source; the remedy in both readings is URL-based accounts

Example fix

// before
export AZURE_STORAGE_ACCOUNT=mystorage
kops ... KOPS_STATE_STORE=azureblob://mystorage/container
// after
unset AZURE_STORAGE_ACCOUNT
export KOPS_STATE_STORE=azureblob://mystorage/container
kops ...
Defensive patterns

Strategy: validation

Validate before calling

if os.Getenv("AZURE_STORAGE_ACCOUNT") != "" { return errors.New("AZURE_STORAGE_ACCOUNT must be unset; embed the account in the URL as azureblob://<account>/<container>/<key>") }

Try / catch

if _, err := context.BuildVfsPath(p); err != nil { if strings.Contains(err.Error(), "AZURE_STORAGE_ACCOUNT") { /* advise unsetting the env var and using the URL form */ } return err }

Prevention

When it happens

Trigger: Calling BuildVfsPath with an azureblob:// path while the AZURE_STORAGE_ACCOUNT environment variable has a non-empty value, causing buildAzureBlobPath to reject the call immediately.

Common situations: Developer has AZURE_STORAGE_ACCOUNT exported in their shell from Azure CLI/SDK workflows (az CLI, older SDK tooling) and then runs kops against an azureblob:// state store; CI environment pre-loading Azure SDK env vars; migration from SDK-style config to URL-based config.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/4edf8d3ab7014752. Report an issue: GitHub.