{"record":{"id":"c49f96e9d8786d74","repo":"kubernetes/kops","slug":"error-parsing-etcd-cluster-tag-q-on-volume-q-v-c49f96","errorCode":null,"errorMessage":"error parsing etcd cluster tag %q on volume %q: %v","messagePattern":"error parsing etcd cluster tag %q on volume %q: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/do/cloud.go","lineNumber":354,"sourceCode":"\t\tfor _, myTag := range volume.Tags {\n\t\t\tklog.V(8).Infof(\"findEtcdStatus status (from cloud): checking if volume with tag %q belongs to cluster\", myTag)\n\t\t\t// check if volume belongs to this cluster.\n\t\t\t// tag will be in the format \"KubernetesCluster:dev5-k8s-local\" (where clusterName is dev5.k8s.local)\n\t\t\tclusterName := strings.ReplaceAll(cluster.Name, \".\", \"-\")\n\t\t\tif strings.Contains(myTag, fmt.Sprintf(\"%s:%s\", TagKubernetesClusterNamePrefix, clusterName)) {\n\t\t\t\tklog.V(10).Infof(\"findEtcdStatus cluster comparison matched for tag: %v\", myTag)\n\t\t\t\t// this volume belongs to our cluster, add this to our etcdClusterSpec.\n\t\t\t\t// loop through the tags again and\n\t\t\t\tfor _, volumeTag := range volume.Tags {\n\t\t\t\t\tif strings.Contains(volumeTag, TagKubernetesClusterIndex) {\n\t\t\t\t\t\tvolumeTagParts := strings.Split(volumeTag, \":\")\n\t\t\t\t\t\tif len(volumeTagParts) < 2 {\n\t\t\t\t\t\t\treturn nil, fmt.Errorf(\"volume tag split failed, too few components for tag %q on volume %q\", volumeTag, volume)\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdropletIndex := volumeTagParts[1]\n\t\t\t\t\t\tetcdClusterSpec, err = c.getEtcdClusterSpec(volume.Name, dropletIndex)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\treturn nil, fmt.Errorf(\"error parsing etcd cluster tag %q on volume %q: %v\", volumeTag, volumeID, err)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tklog.V(10).Infof(\"findEtcdStatus etcdClusterSpec: %v\", fi.DebugAsJsonString(etcdClusterSpec))\n\t\t\t\t\t\tetcdClusterName = etcdClusterSpec.ClusterKey\n\t\t\t\t\t\tstatus := statusMap[etcdClusterName]\n\t\t\t\t\t\tif status == nil {\n\t\t\t\t\t\t\tstatus = &kops.EtcdClusterStatus{\n\t\t\t\t\t\t\t\tName: etcdClusterName,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tstatusMap[etcdClusterName] = status\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tmemberName := etcdClusterSpec.NodeName\n\t\t\t\t\t\tstatus.Members = append(status.Members, &kops.EtcdMemberStatus{\n\t\t\t\t\t\t\tName:     memberName,\n\t\t\t\t\t\t\tVolumeID: volume.ID,\n\t\t\t\t\t\t})\n\t\t\t\t\t}","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/do/cloud.go#L336-L372","documentation":"After splitting the volume's index tag, findEtcdStatus calls c.getEtcdClusterSpec(volume.Name, dropletIndex) to derive the etcd cluster spec from the volume name. Any error from that call (see the 'could not determine etcd cluster type' case) is re-wrapped with the tag and volume ID for context, and aborts etcd status discovery.","triggerScenarios":"getEtcdClusterSpec fails because the volume name does not contain 'etcd-main' or 'etcd-events' (the only recognized types), producing an inner error that surfaces wrapped as this message.","commonSituations":"Volumes tagged as belonging to the cluster but named outside kOps conventions (manually renamed volumes, volumes from other tooling sharing the cluster tag); kOps convention changes across versions.","solutions":["Check the volume's name: it must contain 'etcd-main' or 'etcd-events' to be classified.","Rename the volume to the kOps convention (e.g. '<cluster>-dyn-etcd-events-<n>') or remove its cluster tag if it isn't a kOps etcd volume.","Look at the inner %v error in the message — it names the actual root cause from getEtcdClusterSpec.","Recreate misnamed etcd volumes through kOps if renaming is not acceptable (data-loss caution)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if !strings.Contains(volume.Name, \"etcd-main\") && !strings.Contains(volume.Name, \"etcd-events\") {\n    return fmt.Errorf(\"volume %s is not a recognized kOps etcd volume\", volume.ID)\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"error parsing etcd cluster tag\") {\n    return auditVolumeNaming(cluster) // check inner cause, fix name/tags\n}","preventionTips":["Keep kOps etcd volume names intact; never rename manually.","Strip cluster tags from non-kOps volumes sharing the tag prefix.","Verify the inner error (%v) to target the actual root cause.","Recreate misnamed volumes via kOps only with etcd data safety confirmed."],"tags":["digitalocean","storage","etcd","tag-validation"],"backgroundTag":"malformed-tag-format","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"}