{"record":{"id":"83825e29bddd5faf","repo":"kubernetes/kops","slug":"error-describing-volumes-v-83825e","errorCode":null,"errorMessage":"error describing volumes: %v","messagePattern":"error describing volumes: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/openstack/status.go","lineNumber":69,"sourceCode":"\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\n// findEtcdStatus discovers the status of etcd, by looking for the tagged etcd volumes\nfunc findEtcdStatus(c OpenstackCloud, cluster *kops.Cluster) ([]kops.EtcdClusterStatus, error) {\n\tstatusMap := make(map[string]*kops.EtcdClusterStatus)\n\tklog.V(2).Infof(\"Querying Openstack for etcd volumes\")\n\topt := cinderv3.ListOpts{\n\t\tMetadata: c.GetCloudTags(),\n\t}\n\tvolumes, err := c.ListVolumes(opt)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error describing volumes: %v\", err)\n\t}\n\n\tfor _, volume := range volumes {\n\t\tvolumeID := volume.ID\n\n\t\tetcdClusterName := \"\"\n\t\tvar etcdClusterSpec *etcd.EtcdClusterSpec\n\n\t\tmaster := false\n\t\tfor k, v := range volume.Metadata {\n\t\t\tif strings.HasPrefix(k, TagNameEtcdClusterPrefix) {\n\t\t\t\tetcdClusterName := strings.TrimPrefix(k, TagNameEtcdClusterPrefix)\n\t\t\t\tetcdClusterSpec, err = etcd.ParseEtcdClusterSpec(etcdClusterName, v)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, fmt.Errorf(\"error parsing etcd cluster tag %q on volume %q: %v\", v, volumeID, err)\n\t\t\t\t}\n\t\t\t} else if k == TagNameRolePrefix+TagRoleControlPlane || k == TagNameRolePrefix+TagRoleMaster {\n\t\t\t\tmaster = true","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/openstack/status.go#L51-L87","documentation":"findEtcdStatus queries the OpenStack Cinder v3 API for volumes tagged with etcd cluster metadata, filtering by the cluster's cloud tags. When c.ListVolumes(opt) fails (API call, auth, or pagination error), the underlying error is wrapped as \"error describing volumes: %v\" and returned to findClusterStatus. This aborts cluster status discovery since etcd state cannot be determined.","triggerScenarios":"OpenStack API endpoint unreachable, invalid/expired Keystone token, neutron/cinder service outage, or a malformed ListOpts metadata filter causing the cinder API to reject the request.","commonSituations":"Expired cloud credentials in the environment, misconfigured OS_* environment variables, network partition between the kops host and the OpenStack cloud, or cinder service down during cluster upgrade/status checks.","solutions":["Verify OpenStack credentials and that `openstack volume list` works with the same env/auth","Check the wrapped underlying error message for 401 (re-authenticate) vs timeout (network/service)","Retry the kops command once the cinder service is healthy","Confirm the cluster's cloud tags in the spec are valid metadata keys"],"exampleFix":"// before\nvolumes, err := c.ListVolumes(opt)\nif err != nil {\n\treturn nil, fmt.Errorf(\"error describing volumes: %v\", err)\n}\n// after (preserve %w for wrapping and add context)\nvolumes, err := c.ListVolumes(opt)\nif err != nil {\n\treturn nil, fmt.Errorf(\"error describing volumes: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"// Go: check credentials/API reachability before running kops\nif err := exec.Command(\"openstack\", \"volume\", \"list\", \"--limit\", \"1\").Run(); err != nil {\n\tlog.Fatal(\"OpenStack cinder API unreachable or credentials invalid\")\n}","typeGuard":"func isAuthFailure(err error) bool {\n\treturn err != nil && strings.Contains(err.Error(), \"401\")\n}","tryCatchPattern":"status, err := findClusterStatus(cloud)\nif err != nil {\n\tvar wrapped *fmt.WrapError\n\tif strings.Contains(err.Error(), \"error describing volumes\") && isAuthFailure(err) {\n\t\t// refresh token and retry\n\t}\n\treturn fmt.Errorf(\"cluster status unavailable: %w\", err)\n}","preventionTips":["Keep OS_* credentials fresh (token expiry monitoring)","Pre-verify cinder access with openstack CLI before kops runs","Monitor OpenStack service health endpoints","Pin cloud tags in the cluster spec to valid metadata keys"],"tags":["openstack","cinder","storage","etcd"],"backgroundTag":"openstack-api-call-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"}