{"record":{"id":"fc7cc13c3f454fde","repo":"kubernetes/kops","slug":"error-listing-disks-s","errorCode":null,"errorMessage":"error listing disks: %s","messagePattern":"error listing disks: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/azure/status.go","lineNumber":38,"sourceCode":"\t\"context\"\n\t\"fmt\"\n\t\"strings\"\n\n\tcompute \"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute\"\n\tv1 \"k8s.io/api/core/v1\"\n\t\"k8s.io/klog/v2\"\n\t\"k8s.io/kops/pkg/apis/kops\"\n\t\"k8s.io/kops/pkg/cloudinstances\"\n\t\"k8s.io/kops/pkg/etcd\"\n\t\"k8s.io/kops/upup/pkg/fi\"\n)\n\n// FindClusterStatus discovers the status of the cluster by looking for the tagged etcd volume.\nfunc (c *azureCloudImplementation) FindClusterStatus(cluster *kops.Cluster) (*kops.ClusterStatus, error) {\n\tklog.V(2).Infof(\"Listing Azure managed disks.\")\n\tdisks, err := c.Disk().List(context.TODO(), cluster.AzureResourceGroupName())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error listing disks: %s\", err)\n\t}\n\n\tetcdStatus, err := c.findEtcdStatus(disks)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstatus := &kops.ClusterStatus{\n\t\tEtcdClusters: etcdStatus,\n\t}\n\tklog.V(2).Infof(\"Cluster status (from cloud): %v\", fi.DebugAsJsonString(status))\n\treturn status, nil\n}\n\nfunc (c *azureCloudImplementation) findEtcdStatus(disks []*compute.Disk) ([]kops.EtcdClusterStatus, error) {\n\tstatusMap := make(map[string]*kops.EtcdClusterStatus)\n\tfor _, disk := range disks {\n\t\tif !c.isDiskForCluster(disk) {\n\t\t\tcontinue","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/azure/status.go#L20-L56","documentation":"kOps' azureCloudImplementation.FindClusterStatus fails while listing managed disks in the cluster resource group via c.Disk().List. Cluster status discovery depends on enumerating tagged etcd volumes, so the whole status lookup fails. Note it uses %s (not %w), so the chain is not unwrappable.","triggerScenarios":"Disk().List(ctx, cluster.AzureResourceGroupName()) returns error: nonexistent resource group, 403 missing Microsoft.Compute/disks/read, throttling, or transient ARM 5xx.","commonSituations":"kops get cluster --cloud=azure against a cluster whose resource group was deleted; identity without disk read permissions; Azure API throttling in a busy subscription.","solutions":["Verify the cluster's resource group name exists (az group show -n <rg>)","Grant the identity Microsoft.Compute/disks/read on the resource group","Fix the root cause inside Disk().List; consider switching to %w wrapping for unwrappability","Retry on throttling honoring Retry-After"],"exampleFix":"// before\nreturn nil, fmt.Errorf(\"error listing disks: %s\", err)\n// after\nreturn nil, fmt.Errorf(\"error listing disks: %w\", err)","handlingStrategy":"try-catch","validationCode":"groups, err := rgClient.Get(ctx, cluster.AzureResourceGroupName(), nil)\nif err != nil {\n\treturn fmt.Errorf(\"resource group for cluster missing: %w\", err)\n}","typeGuard":"var respErr *azcore.ResponseError\nif errors.As(err, &respErr) {\n\tif respErr.ErrorCode == \"ResourceGroupNotFound\" {\n\t\t// cluster fully deleted; return empty status instead of failing\n\t}\n}","tryCatchPattern":"status, err := cloud.FindClusterStatus(cluster)\nif err != nil {\n\tvar respErr *azcore.ResponseError\n\tif errors.As(err, &respErr) && respErr.StatusCode == 403 {\n\t\treturn fmt.Errorf(\"need Microsoft.Compute/disks/read on %s\", cluster.AzureResourceGroupName())\n\t}\n\treturn err\n}","preventionTips":["Grant the identity disk read access on the cluster resource group","Verify the resource group exists before status discovery","Prefer %w over %s wrapping so callers can errors.As on ResponseError"],"tags":["azure","disks","cluster-status","etcd"],"backgroundTag":"azure-list-resources-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}