{"record":{"id":"07c5b340807c07ef","repo":"kubernetes/kops","slug":"error-parsing-etcd-cluster-tag-q-on-volume-q-s","errorCode":null,"errorMessage":"error parsing etcd cluster tag %q on volume %q: %s","messagePattern":"error parsing etcd cluster tag %q on volume %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/azure/status.go","lineNumber":75,"sourceCode":"\t\t}\n\n\t\tvar (\n\t\t\tetcdClusterName string\n\t\t\tetcdClusterSpec *etcd.EtcdClusterSpec\n\t\t\tmaster          bool\n\t\t)\n\t\tfor k, v := range disk.Tags {\n\t\t\tif k == TagNameRolePrefix+TagRoleControlPlane || k == TagNameRolePrefix+TagRoleMaster {\n\t\t\t\tmaster = true\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif strings.HasPrefix(k, TagNameEtcdClusterPrefix) {\n\t\t\t\tetcdClusterName = strings.TrimPrefix(k, TagNameEtcdClusterPrefix)\n\t\t\t\tvar err error\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: %s\", *v, *disk.Name, err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif etcdClusterName == \"\" || etcdClusterSpec == nil || !master {\n\t\t\tcontinue\n\t\t}\n\n\t\tstatus := statusMap[etcdClusterName]\n\t\tif status == nil {\n\t\t\tstatus = &kops.EtcdClusterStatus{\n\t\t\t\tName: etcdClusterName,\n\t\t\t}\n\t\t\tstatusMap[etcdClusterName] = status\n\t\t}\n\t\tstatus.Members = append(status.Members, &kops.EtcdMemberStatus{\n\t\t\tName:     etcdClusterSpec.NodeName,\n\t\t\tVolumeID: *disk.Name,","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/azure/status.go#L57-L93","documentation":"Raised in findEtcdStatus when etcd.ParseEtcdClusterSpec cannot parse the value of a tag whose key starts with TagNameEtcdClusterPrefix on a master disk. The tag value encodes the etcd cluster spec (members, names); malformed values abort status discovery for the whole cluster.","triggerScenarios":"A disk tagged k8s.io/etcd/<clusterName> has a value that fails ParseEtcdClusterSpec — e.g., wrong member count syntax, empty value, or hand-edited/legacy tag format.","commonSituations":"Tags manually edited in the Azure portal; clusters created by older kOps versions with a spec format the current parser rejects; copy-paste tag typos when migrating disks.","solutions":["Inspect the disk's etcd tags in the Azure portal and correct the tag value format","Re-apply the intended etcd cluster spec via kops rather than manual tag editing","Confirm kOps version consistency between cluster creation and status discovery","Skip or log-and-continue for unparseable tags if the disk is not an etcd master volume"],"exampleFix":"// before\ntag: \"a=1\" // malformed etcd spec\n// after\n// correct etcd cluster spec format, e.g. \"master-us-east-1a=1/1\"\ntag: \"master-us-east-1a=1/1\"","handlingStrategy":"validation","validationCode":"for k, v := range disk.Tags {\n\tif strings.HasPrefix(k, TagNameEtcdClusterPrefix) {\n\t\tif _, err := etcd.ParseEtcdClusterSpec(strings.TrimPrefix(k, TagNameEtcdClusterPrefix), *v); err != nil {\n\t\t\tklog.Warningf(\"skipping disk %s: invalid etcd tag %q\", *disk.Name, *v)\n\t\t\tcontinue\n\t\t}\n\t}\n}","typeGuard":null,"tryCatchPattern":"spec, err := findEtcdStatus(disks)\nif err != nil {\n\treturn fmt.Errorf(\"etcd status discovery failed; check etcd tags on disks: %w\", err)\n}","preventionTips":["Never hand-edit etcd tags on Azure disks; manage them via kops","Keep the kOps version that created the cluster when inspecting it","Use consistent etcd cluster spec format across volumes"],"tags":["azure","etcd","tags","parsing"],"backgroundTag":"etcd-cluster-tag-invalid","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"}