kubernetes/kops · error
expected azureblob:// URL, got %q
Error message
expected azureblob:// URL, got %q
What it means
azureBlobAccount builds a vfs path from a raw azureblob:// URL and asserts the result is an *vfs.AzureBlobPath. If vfs.Context.BuildVfsPath returns a different path type (or the URL is not a valid azureblob URL), the function cannot extract a storage account name and returns this error. It is used by validateAzureBlobAccountUniformity to compare storage accounts across the cluster spec.
Source
Thrown at pkg/apis/kops/validation/validation.go:1660
}
return allErrs
}
// azureBlobAccount returns the storage account encoded in an azureblob:// URL,
// or "" with no error if the URL is not azureblob://. Returns an error only if
// the URL has the azureblob:// prefix but fails to parse.
func azureBlobAccount(rawURL string) (string, error) {
if !strings.HasPrefix(rawURL, "azureblob://") {
return "", nil
}
p, err := vfs.Context.BuildVfsPath(rawURL)
if err != nil {
return "", err
}
azPath, ok := p.(*vfs.AzureBlobPath)
if !ok {
return "", fmt.Errorf("expected azureblob:// URL, got %q", rawURL)
}
return azPath.Account(), nil
}
// validateAzureBlobAccountUniformity enforces that every azureblob:// URL in
// the cluster spec uses the same storage account as configStore.base. Any
// azureblob:// URL elsewhere in the spec is rejected when configStore.base is
// not itself azureblob://.
func validateAzureBlobAccountUniformity(spec *kops.ClusterSpec, fieldPath *field.Path) field.ErrorList {
var allErrs field.ErrorList
csPath := fieldPath.Child("configStore")
canonical := ""
if strings.HasPrefix(spec.ConfigStore.Base, "azureblob://") {
account, err := azureBlobAccount(spec.ConfigStore.Base)
if err != nil {
allErrs = append(allErrs, field.Invalid(csPath.Child("base"), spec.ConfigStore.Base, err.Error()))
return allErrsView on GitHub (pinned to 4c8573c808)
Solutions
- Use a well-formed URL of the form azureblob://<account>/<container>/<path> for all cluster storage locations.
- Verify the scheme is exactly `azureblob://` (two slashes) and that vfs can parse it (test with `kops get cluster` or a small vfs.Context.BuildVfsPath call).
- If uniformity validation fails, ensure every azureblob:// URL in the spec uses the same storage account as configStore.base.
Example fix
// before configBase: s3://my-bucket/cluster.example.com // after configBase: azureblob://mystorageaccount/kops/cluster.example.com
Defensive patterns
Strategy: type-guard
Validate before calling
u, err := url.Parse(rawURL)
if err != nil || u.Scheme != "azureblob" {
return fmt.Errorf("not an azureblob URL: %q", rawURL)
} Type guard
func isAzureBlobPath(p vfs.Path) (*vfs.AzureBlobPath, bool) {
az, ok := p.(*vfs.AzureBlobPath)
return az, ok
} Prevention
- Standardize on azureblob://<account>/<container>/<path> for all cluster storage fields.
- Validate URLs with vfs.Context.BuildVfsPath in CI before applying cluster changes.
- When migrating from S3/GCS, sed-check every URL field for leftover schemes.
When it happens
Trigger: Passing a non-azureblob URL (e.g. s3://, file://, or a malformed azureblob:// string) into azureBlobAccount; BuildVfsPath parses it into a different vfs.Path concrete type so the type assertion fails.
Common situations: Configuring configBase or a mirror with the wrong scheme when migrating a cluster to Azure; copy-pasting an S3 or Azure Files (file://) URL; a typo like azureblob:/account (single slash) that parses as something else.
Related errors
- unexpected kind for cluster, got %T, want kops.Cluster
- method ConfigBaseFor not supported in server-side client
- ResourceVersion not supported in InstanceGroupVFS::Get
- reading file %q: %v
- building vfs path: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/dbec4f1cd05349a8.
Report an issue: GitHub.