{"record":{"id":"1017222dd087b1ac","repo":"kubernetes/kops","slug":"backup-store-q-is-azureblob-but-configstore-ba","errorCode":null,"errorMessage":"backup-store %q is azureblob:// but configStore.base %q is not","messagePattern":"backup-store %q is azureblob:// but configStore\\.base %q is not","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/components/etcdmanager/model.go","lineNumber":78,"sourceCode":"func resolveAzureBackupStore(configStoreBase, backupStore string) (legacyURL string, storageAccount string, err error) {\n\tif !strings.HasPrefix(backupStore, \"azureblob://\") {\n\t\treturn backupStore, \"\", nil\n\t}\n\tbp, err := vfs.Context.BuildVfsPath(backupStore)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"parsing etcd backup-store %q: %w\", backupStore, err)\n\t}\n\tbpAzure, ok := bp.(*vfs.AzureBlobPath)\n\tif !ok {\n\t\treturn \"\", \"\", fmt.Errorf(\"expected azureblob:// backup-store, got %q\", backupStore)\n\t}\n\tcsp, err := vfs.Context.BuildVfsPath(configStoreBase)\n\tif err != nil {\n\t\treturn \"\", \"\", fmt.Errorf(\"parsing configStore.base %q: %w\", configStoreBase, err)\n\t}\n\tcsAzure, ok := csp.(*vfs.AzureBlobPath)\n\tif !ok {\n\t\treturn \"\", \"\", fmt.Errorf(\"backup-store %q is azureblob:// but configStore.base %q is not\", backupStore, configStoreBase)\n\t}\n\tlegacy := \"azureblob://\" + bpAzure.Container()\n\tif bpAzure.Key() != \"\" {\n\t\tlegacy += \"/\" + bpAzure.Key()\n\t}\n\treturn legacy, csAzure.Account(), nil\n}\n\n// EtcdManagerBuilder builds the manifest for the etcd-manager\ntype EtcdManagerBuilder struct {\n\t*model.KopsModelContext\n\tLifecycle    fi.Lifecycle\n\tAssetBuilder *assets.AssetBuilder\n}\n\nvar _ fi.CloudupModelBuilder = &EtcdManagerBuilder{}\n\n// Build creates the tasks","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/components/etcdmanager/model.go#L60-L96","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nconfigStore:\n  base: \"s3://my-bucket/config\"\nbackups:\n  backupStore: \"azureblob://myaccount/etcd-backups\"\n// after\nconfigStore:\n  base: \"azureblob://myaccount/etcd-config\"\nbackups:\n  backupStore: \"azureblob://myaccount/etcd-backups\"","handlingStrategy":"type-guard","validationCode":"if strings.HasPrefix(backupStore, \"azureblob://\") && !strings.HasPrefix(configStoreBase, \"azureblob://\") {\n    return fmt.Errorf(\"configStore.base must also be azureblob:// when backupStore is azureblob://\")\n}","typeGuard":"func bothAzure(bp, cp vfs.VFSPath) bool {\n    _, okB := bp.(*vfs.AzureBlobPath)\n    _, okC := cp.(*vfs.AzureBlobPath)\n    return okB && okC\n}","tryCatchPattern":"legacy, account, err := resolveAzureBackupStore(configStoreBase, backupStore)\nif err != nil {\n    if strings.Contains(err.Error(), \"is azureblob:// but configStore.base\") {\n        // align configStore.base to azureblob:// and retry\n    }\n    return err\n}","preventionTips":["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"],"tags":["azure","etcd","type-mismatch","config"],"backgroundTag":"unsupported-storage-backend","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}