kubernetes/kops · error

Error appending tag to network: %v

Error message

Error appending tag to network: %v

What it means

After a network is successfully created, RenderOpenstack calls Cloud.AppendTag to stamp the cluster tag on the new Neutron network. If that tagging API call fails, the network is left created but untagged and kOps aborts the render with this wrapped error.

Source

Thrown at upup/pkg/fi/cloudup/openstacktasks/network.go:134

func (_ *Network) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, changes *Network) error {
	if a == nil {
		klog.V(2).Infof("Creating Network with name:%q", fi.ValueOf(e.Name))

		opt := networks.CreateOpts{
			Name:                  fi.ValueOf(e.Name),
			AdminStateUp:          new(true),
			AvailabilityZoneHints: fi.StringSliceValue(e.AvailabilityZoneHints),
		}

		v, err := t.Cloud.CreateNetwork(opt)
		if err != nil {
			return fmt.Errorf("Error creating network: %v", err)
		}

		err = t.Cloud.AppendTag(openstack.ResourceTypeNetwork, v.ID, fi.ValueOf(e.Tag))
		if err != nil {
			return fmt.Errorf("Error appending tag to network: %v", err)
		}

		e.ID = new(v.ID)
		klog.V(2).Infof("Creating a new Openstack network, id=%s", v.ID)
		return nil
	} else {
		err := t.Cloud.AppendTag(openstack.ResourceTypeNetwork, fi.ValueOf(a.ID), fi.ValueOf(changes.Tag))
		if err != nil {
			return fmt.Errorf("Error appending tag to network: %v", err)
		}
	}
	e.ID = a.ID
	klog.V(2).Infof("Using an existing Openstack network, id=%s", fi.ValueOf(e.ID))
	return nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the wrapped gophercloud error for the HTTP status of the tag PUT
  2. Confirm the Neutron `tag` extension is enabled (`openstack extension list`) on the deployment
  3. Verify the cluster Tag value contains only valid tag characters (no spaces/special chars)
  4. Re-run `kops update cluster`: the network now exists and render will take the update path
  5. Re-authenticate if the error was 401; check token TTL vs cluster update duration

Example fix

// before
tag: "my cluster tag"
// after
tag: "my-cluster-tag" // Neutron tags disallow spaces
Defensive patterns

Strategy: retry

Validate before calling

// ensure tag extension exists
out, err := exec.Command("openstack", "extension", "list", "--tag", "tag").Output()
if err != nil || len(out) == 0 { /* tagging unsupported; skip or upgrade Neutron */ }
// validate tag chars
validTag := regexp.MustCompile(`^[\w.\-]+$`).MatchString(tag)

Type guard

func isValidNeutronTag(tag string) bool {
	return len(tag) > 0 && len(tag) <= 255 && regexp.MustCompile(`^[\w.\-]+$`).MatchString(tag)
}

Try / catch

err = t.Cloud.AppendTag(openstack.ResourceTypeNetwork, v.ID, tag)
if err != nil {
	if isTransient(err) { // 5xx/timeout
		return retryAfter(backoff) // network exists; safe to retry append
	}
	return fmt.Errorf("Error appending tag to network: %v", err)
}

Prevention

When it happens

Trigger: Cloud.AppendTag(openstack.ResourceTypeNetwork, v.ID, tag) fails right after CreateNetwork succeeds: the network ID is fresh but the tag PUT is rejected (401/403, tag extension disabled in Neutron, transient 503, or tag string violating Neutron tag character rules).

Common situations: Older Neutron deployments without the default tagging extension enabled; Keystone token expiring mid-run; a tag value containing invalid characters set in the cluster spec; intermittent Neutron 503 during a large cluster create.

Related errors


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