kubernetes/kops · error

error parsing etcd cluster tag %q on volume %q: %v

Error message

error parsing etcd cluster tag %q on volume %q: %v

What it means

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.

Source

Thrown at upup/pkg/fi/cloudup/do/cloud.go:354

		for _, myTag := range volume.Tags {
			klog.V(8).Infof("findEtcdStatus status (from cloud): checking if volume with tag %q belongs to cluster", myTag)
			// check if volume belongs to this cluster.
			// tag will be in the format "KubernetesCluster:dev5-k8s-local" (where clusterName is dev5.k8s.local)
			clusterName := strings.ReplaceAll(cluster.Name, ".", "-")
			if strings.Contains(myTag, fmt.Sprintf("%s:%s", TagKubernetesClusterNamePrefix, clusterName)) {
				klog.V(10).Infof("findEtcdStatus cluster comparison matched for tag: %v", myTag)
				// this volume belongs to our cluster, add this to our etcdClusterSpec.
				// loop through the tags again and
				for _, volumeTag := range volume.Tags {
					if strings.Contains(volumeTag, TagKubernetesClusterIndex) {
						volumeTagParts := strings.Split(volumeTag, ":")
						if len(volumeTagParts) < 2 {
							return nil, fmt.Errorf("volume tag split failed, too few components for tag %q on volume %q", volumeTag, volume)
						}
						dropletIndex := volumeTagParts[1]
						etcdClusterSpec, err = c.getEtcdClusterSpec(volume.Name, dropletIndex)
						if err != nil {
							return nil, fmt.Errorf("error parsing etcd cluster tag %q on volume %q: %v", volumeTag, volumeID, err)
						}

						klog.V(10).Infof("findEtcdStatus etcdClusterSpec: %v", fi.DebugAsJsonString(etcdClusterSpec))
						etcdClusterName = etcdClusterSpec.ClusterKey
						status := statusMap[etcdClusterName]
						if status == nil {
							status = &kops.EtcdClusterStatus{
								Name: etcdClusterName,
							}
							statusMap[etcdClusterName] = status
						}

						memberName := etcdClusterSpec.NodeName
						status.Members = append(status.Members, &kops.EtcdMemberStatus{
							Name:     memberName,
							VolumeID: volume.ID,
						})
					}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the volume's name: it must contain 'etcd-main' or 'etcd-events' to be classified.
  2. 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.
  3. Look at the inner %v error in the message — it names the actual root cause from getEtcdClusterSpec.
  4. Recreate misnamed etcd volumes through kOps if renaming is not acceptable (data-loss caution).
Defensive patterns

Strategy: validation

Validate before calling

if !strings.Contains(volume.Name, "etcd-main") && !strings.Contains(volume.Name, "etcd-events") {
    return fmt.Errorf("volume %s is not a recognized kOps etcd volume", volume.ID)
}

Try / catch

if err != nil && strings.Contains(err.Error(), "error parsing etcd cluster tag") {
    return auditVolumeNaming(cluster) // check inner cause, fix name/tags
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/c49f96e9d8786d74. Report an issue: GitHub.