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 finding etcd volumes, kOps scans each volume's metadata for keys prefixed with TagNameEtcdClusterPrefix and parses the value with etcd.ParseEtcdClusterSpec. If the tag value is not a valid serialized etcd cluster spec, the parse error is wrapped as "error parsing etcd cluster tag %q on volume %q". This indicates corrupted or hand-edited etcd metadata on the volume.

Source

Thrown at upup/pkg/fi/cloudup/openstack/status.go:84

	}
	volumes, err := c.ListVolumes(opt)
	if err != nil {
		return nil, fmt.Errorf("error describing volumes: %v", err)
	}

	for _, volume := range volumes {
		volumeID := volume.ID

		etcdClusterName := ""
		var etcdClusterSpec *etcd.EtcdClusterSpec

		master := false
		for k, v := range volume.Metadata {
			if strings.HasPrefix(k, TagNameEtcdClusterPrefix) {
				etcdClusterName := strings.TrimPrefix(k, TagNameEtcdClusterPrefix)
				etcdClusterSpec, err = etcd.ParseEtcdClusterSpec(etcdClusterName, v)
				if err != nil {
					return nil, fmt.Errorf("error parsing etcd cluster tag %q on volume %q: %v", v, volumeID, err)
				}
			} else if k == TagNameRolePrefix+TagRoleControlPlane || k == TagNameRolePrefix+TagRoleMaster {
				master = true
			}
		}
		if etcdClusterSpec == nil || !master {
			continue
		}

		etcdClusterName = etcdClusterSpec.ClusterKey
		status := statusMap[etcdClusterName]
		if status == nil {
			status = &kops.EtcdClusterStatus{
				Name: etcdClusterName,
			}
			statusMap[etcdClusterName] = status
		}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the volume metadata in OpenStack and fix or remove the offending k8s.io/etcd/* key
  2. Check kOps release notes for etcd spec format changes affecting your cluster version
  3. Restore the metadata from a known-good backup or recreate the volume via kops
  4. If the volume is orphaned, delete it after confirming it is not backing a live etcd member

Example fix

// before (note: inner := shadows the outer etcdClusterName variable)
etcdClusterName := strings.TrimPrefix(k, TagNameEtcdClusterPrefix)
etcdClusterSpec, err = etcd.ParseEtcdClusterSpec(etcdClusterName, v)
// after
etcdClusterName = strings.TrimPrefix(k, TagNameEtcdClusterPrefix)
etcdClusterSpec, err = etcd.ParseEtcdClusterSpec(etcdClusterName, v)
Defensive patterns

Strategy: validation

Validate before calling

// Validate volume metadata before treating it as an etcd spec
for k, v := range volume.Metadata {
	if strings.HasPrefix(k, TagNameEtcdClusterPrefix) {
		if err := json.Unmarshal([]byte(v), &map[string]interface{}{}); err != nil {
			log.Printf("volume %s has malformed etcd tag value %q", volumeID, v)
		}
	}
}

Prevention

When it happens

Trigger: A volume carries a key like k8s.io/etcd/<name> whose value is malformed JSON or was produced by an incompatible kOps version; ParseEtcdClusterSpec rejects it.

Common situations: Manual edits to Cinder volume metadata, volume reuse from a cluster created by a much older/newer kops, or metadata truncated/modified by another automation tool.

Related errors


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