kubernetes/kops · error

building node labels for %q: %w

Error message

building node labels for %q: %w

What it means

buildKarpenterNodePool calls nodelabels.BuildNodeLabels to compute Kubernetes node labels for the InstanceGroup; when that helper fails, the error is wrapped as 'building node labels for %q: %w'. It blocks rendering of the Karpenter NodePool manifest during template expansion.

Source

Thrown at upup/pkg/fi/cloudup/template_functions_karpenter.go:407

	}
	resolved, err := cloud.ResolveImage(image)
	if err != nil {
		return "", fmt.Errorf("unable to resolve image %q: %w", image, err)
	}
	if resolved == nil {
		return "", fmt.Errorf("unable to resolve image %q: not found", image)
	}
	rootDeviceName := fi.ValueOf(resolved.RootDeviceName)
	if rootDeviceName == "" {
		return "", fmt.Errorf("image %q has no root device name", image)
	}
	return rootDeviceName, nil
}

func (tf *TemplateFunctions) buildKarpenterNodePool(ig *kops.InstanceGroup) (*karpenterNodePool, error) {
	labels, err := nodelabels.BuildNodeLabels(tf.Cluster, ig)
	if err != nil {
		return nil, fmt.Errorf("building node labels for %q: %w", ig.Name, err)
	}
	labels = karpenterNodePoolTemplateLabels(labels)

	template := karpenterNodeClaimTemplate{
		Spec: karpenterNodeClaimSpec{
			Requirements: tf.karpenterRequirements(ig),
			NodeClassRef: karpenterNodeClassRef{
				Group: karpenterAWSAPIGroup,
				Kind:  "EC2NodeClass",
				Name:  ig.Name,
			},
		},
	}
	if len(labels) != 0 {
		template.Metadata = &karpenterNodeClaimMetadata{Labels: labels}
	}
	for _, taintSpec := range ig.Spec.Taints {
		taint, err := kopsutil.ParseTaint(taintSpec)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped inner error for the offending label
  2. Fix nodeLabels in the instance group spec to be valid Kubernetes label key/value pairs (RFC 1123 DNS labels)
  3. Remove or rename labels that conflict with reserved kops/system labels
  4. Re-run `kops update cluster`

Example fix

// before
nodeLabels:
  MyLabel/Env: Production
// after
nodeLabels:
  mylabel/env: production
Defensive patterns

Strategy: validation

Validate before calling

// validate nodeLabels before update
for k, v := range ig.Spec.NodeLabels {
	if err := labels.ValidateLabelKey(k); err != nil || err := labels.ValidateLabelValue(k, v); err != nil {
		return fmt.Errorf("invalid node label %s=%s: %w", k, v, err)
	}
}

Try / catch

if err != nil && strings.Contains(err.Error(), "building node labels") {
	return fmt.Errorf("fix nodeLabels for instance group: %w", err)
}

Prevention

When it happens

Trigger: BuildNodeLabels returns an error while building a NodePool for an InstanceGroup — e.g. an invalid label key/value in the InstanceGroup spec or cluster config that fails validation by the nodelabels package.

Common situations: InstanceGroup spec nodeLabels containing characters invalid in Kubernetes label keys/values (uppercase, illegal prefixes, too long), or reserved kops label collisions.

Related errors


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