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
- Inspect the volume metadata in OpenStack and fix or remove the offending k8s.io/etcd/* key
- Check kOps release notes for etcd spec format changes affecting your cluster version
- Restore the metadata from a known-good backup or recreate the volume via kops
- 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
- Never hand-edit Cinder volume metadata on kops-managed volumes
- Keep kops and cluster spec versions aligned (etcd spec format changes)
- Back up volume metadata before maintenance
- Audit volume tags after external automation touches volumes
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
- invalid EtcdClusterSpec (expected two tokens): %q
- invalid EtcdClusterSpec (member not found in all nodes): %q
- error parsing etcd cluster tag %q on volume %q: %s
- error getting cloud instance group %q: %v
- unable to fetch metadata: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/b8a5e209dd8fdf0b.
Report an issue: GitHub.