kubernetes/kops · error
backup-store %q is azureblob:// but configStore.base %q is n
Error message
backup-store %q is azureblob:// but configStore.base %q is not
What it means
For the legacy Azure etcd backup URL derivation, both the backupStore and configStore.base must live in Azure Blob Storage (vfs.AzureBlobPath), since the storage account is read from the config store. If the backup store is azureblob:// but configStore.base resolves to another backend type, this error is returned.
Source
Thrown at pkg/model/components/etcdmanager/model.go:78
func resolveAzureBackupStore(configStoreBase, backupStore string) (legacyURL string, storageAccount string, err error) {
if !strings.HasPrefix(backupStore, "azureblob://") {
return backupStore, "", nil
}
bp, err := vfs.Context.BuildVfsPath(backupStore)
if err != nil {
return "", "", fmt.Errorf("parsing etcd backup-store %q: %w", backupStore, err)
}
bpAzure, ok := bp.(*vfs.AzureBlobPath)
if !ok {
return "", "", fmt.Errorf("expected azureblob:// backup-store, got %q", backupStore)
}
csp, err := vfs.Context.BuildVfsPath(configStoreBase)
if err != nil {
return "", "", fmt.Errorf("parsing configStore.base %q: %w", configStoreBase, err)
}
csAzure, ok := csp.(*vfs.AzureBlobPath)
if !ok {
return "", "", fmt.Errorf("backup-store %q is azureblob:// but configStore.base %q is not", backupStore, configStoreBase)
}
legacy := "azureblob://" + bpAzure.Container()
if bpAzure.Key() != "" {
legacy += "/" + bpAzure.Key()
}
return legacy, csAzure.Account(), nil
}
// EtcdManagerBuilder builds the manifest for the etcd-manager
type EtcdManagerBuilder struct {
*model.KopsModelContext
Lifecycle fi.Lifecycle
AssetBuilder *assets.AssetBuilder
}
var _ fi.CloudupModelBuilder = &EtcdManagerBuilder{}
// Build creates the tasksView on GitHub (pinned to 4c8573c808)
Solutions
- Set configStore.base to an azureblob:// path in the same (or intended) storage account as the backupStore
- Keep backupStore and configStore.base on the same backend type
- Verify the cluster is actually an Azure cluster and both stores were created for it
Example fix
// before configStore: base: "s3://my-bucket/config" backups: backupStore: "azureblob://myaccount/etcd-backups" // after configStore: base: "azureblob://myaccount/etcd-config" backups: backupStore: "azureblob://myaccount/etcd-backups"
Defensive patterns
Strategy: type-guard
Validate before calling
if strings.HasPrefix(backupStore, "azureblob://") && !strings.HasPrefix(configStoreBase, "azureblob://") {
return fmt.Errorf("configStore.base must also be azureblob:// when backupStore is azureblob://")
} Type guard
func bothAzure(bp, cp vfs.VFSPath) bool {
_, okB := bp.(*vfs.AzureBlobPath)
_, okC := cp.(*vfs.AzureBlobPath)
return okB && okC
} Try / catch
legacy, account, err := resolveAzureBackupStore(configStoreBase, backupStore)
if err != nil {
if strings.Contains(err.Error(), "is azureblob:// but configStore.base") {
// align configStore.base to azureblob:// and retry
}
return err
} Prevention
- Keep etcd configStore.base and backupStore on the same azureblob:// backend
- Audit specs after cloud migrations for mixed backends
- Validate Azure etcd configuration in CI before applying
When it happens
Trigger: An Azure etcd cluster where backups.backupStore starts with azureblob:// but configStore.base is e.g. s3://, file://, or another non-Azure VFS path, encountered during buildPod.
Common situations: Mixed-cloud configuration left from a migration; configStore pointing at a local path while backups use Azure; copy-pasted spec from an AWS cluster with Azure backupStore substituted.
Related errors
- expected azureblob:// backup-store, got %q
- error parsing path for etcd manifest %s: %v
- invalid EtcdClusterSpec (expected two tokens): %q
- invalid EtcdClusterSpec (member not found in all nodes): %q
- parsing etcd backup-store %q: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/1017222dd087b1ac.
Report an issue: GitHub.