kubernetes/kops · error

reading userData for %q: %w

Error message

reading userData for %q: %w

What it means

Returned by buildKarpenterEC2NodeClass when tf.managedFileContents("nodeupscript-"+ig.Name) cannot read the bootstrap script managed file for the instance group. Karpenter nodes get nodeup via this userData, so a missing/unreadable managed file aborts EC2NodeClass construction.

Source

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

	}

	instanceProfile, err := tf.LinkToIAMInstanceProfile(ig)
	if err != nil {
		return nil, fmt.Errorf("building instance profile for %q: %w", ig.Name, err)
	}

	tags, err := tf.CloudTagsForInstanceGroup(ig)
	if err != nil {
		return nil, fmt.Errorf("building tags for %q: %w", ig.Name, err)
	}
	tags = karpenterEC2NodeClassTags(tags)
	associatePublicIP, err := tf.karpenterAssociatePublicIP(ig)
	if err != nil {
		return nil, err
	}
	userData, err := tf.managedFileContents("nodeupscript-" + ig.Name)
	if err != nil {
		return nil, fmt.Errorf("reading userData for %q: %w", ig.Name, err)
	}
	rootDeviceName, err := tf.karpenterRootDeviceName(ig.Spec.Image)
	if err != nil {
		return nil, fmt.Errorf("resolving root device for %q: %w", ig.Name, err)
	}
	blockDeviceMappings, err := buildKarpenterBlockDeviceMappings(ig, rootDeviceName)
	if err != nil {
		return nil, fmt.Errorf("building blockDeviceMappings for %q: %w", ig.Name, err)
	}

	subnetTerms := []karpenterSelectorTerm{
		{
			Tags: map[string]string{
				"KubernetesCluster":                     tf.ClusterName(),
				"kops.k8s.io/instance-group/" + ig.Name: "true",
			},
		},
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Verify a managed file task named "nodeupscript-<ig.Name>" is created for every Karpenter instance group
  2. Check the wrapped error from managedFileContents for the exact missing key
  3. Ensure kops config generation runs before Karpenter template rendering
  4. Confirm instance group names contain no characters breaking the file key

Example fix

// before: ig named with mismatched key
userData, err := tf.managedFileContents("nodeupscript-worker")
// after: derive key from the actual instance group name
userData, err := tf.managedFileContents("nodeupscript-" + ig.Name)
Defensive patterns

Strategy: validation

Validate before calling

// ensure the nodeupscript managed file exists before rendering EC2NodeClass
key := "nodeupscript-" + ig.Name
if !tf.HasManagedFile(key) {
	return fmt.Errorf("managed file %q missing for instance group %q", key, ig.Name)
}

Try / catch

nc, err := tf.KarpenterEC2NodeClass(ig)
if err != nil {
	return fmt.Errorf("userData for %q unavailable: %w", ig.Name, err)
}

Prevention

When it happens

Trigger: The managed file named "nodeupscript-<ig.Name>" does not exist in the build or its contents cannot be resolved when KarpenterEC2NodeClass renders — e.g. the nodeup script task was not created for that instance group.

Common situations: Instance group misnamed so the nodeupscript-<name> file was generated for a different key; bootstrap script generation skipped for Karpenter instance groups; ordering issues where userData is requested before file tasks are built.

Related errors


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