kubernetes/kops · error

error rendering UserData: %s

Error message

error rendering UserData: %s

What it means

In RenderAzure, before creating/updating a VMSS, kOps converts the task's UserData fi.Resource (e.g. nodeup bootstrap script) into bytes with fi.ResourceAsBytes so it can base64-encode it into osProfile.customData. If reading the resource bytes fails, RenderAzure returns this error and the whole apply for the VMSS task fails.

Source

Thrown at upup/pkg/fi/cloudup/azuretasks/vmscaleset.go:281

	}
	return nil
}

// RenderAzure creates or updates a VM Scale Set.
func (s *VMScaleSet) RenderAzure(t *azure.AzureAPITarget, a, e, changes *VMScaleSet) error {
	if a == nil {
		klog.Infof("Creating a new VM Scale Set with name: %s", fi.ValueOf(e.Name))
	} else {
		klog.Infof("Updating a VM Scale Set with name: %s", fi.ValueOf(e.Name))
	}

	name := *e.Name

	var customData *string
	if e.UserData != nil {
		d, err := fi.ResourceAsBytes(e.UserData)
		if err != nil {
			return fmt.Errorf("error rendering UserData: %s", err)
		}
		customData = to.Ptr(base64.StdEncoding.EncodeToString(d))
	}

	osProfile := &compute.VirtualMachineScaleSetOSProfile{
		ComputerNamePrefix: e.ComputerNamePrefix,
		AdminUsername:      e.AdminUser,
		LinuxConfiguration: &compute.LinuxConfiguration{
			SSH: &compute.SSHConfiguration{
				PublicKeys: []*compute.SSHPublicKey{
					{
						Path:    to.Ptr(fmt.Sprintf("/home/%s/.ssh/authorized_keys", *e.AdminUser)),
						KeyData: to.Ptr(*e.SSHPublicKey),
					},
				},
			},
			DisablePasswordAuthentication: to.Ptr(true),
		},

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Re-run the apply; if the source was a remote VFS, check connectivity/credentials to the state store.
  2. If UserData points at a local file, verify the path exists and is readable by the kops process.
  3. Check custom fi.Resource implementations for Read errors; fix or replace with fi.NewBytesResource.
  4. Regenerate the target with `kops update cluster` to rebuild the resource from the cluster spec.

Example fix

// before (unreliable reader)
r := myLazyFileReader(path)
e.UserData = r
// after (read once, surface errors early)
b, err := os.ReadFile(path)
if err != nil { return err }
e.UserData = fi.NewBytesResource(b)
Defensive patterns

Strategy: try-catch

Validate before calling

if e.UserData != nil {
  if _, err := fi.ResourceAsBytes(e.UserData); err != nil {
    return fmt.Errorf("userdata unreadable before apply: %w", err)
  }
}

Try / catch

d, err := fi.ResourceAsBytes(e.UserData)
if err != nil {
  return fmt.Errorf("error rendering UserData: %s", err)
}

Prevention

When it happens

Trigger: RenderAzure (via kops update cluster apply) when e.UserData is non-nil but fi.ResourceAsBytes cannot read it — e.g. a resource backed by an unreadable file path, a failed/closed reader, or a nil/invalid resource implementation.

Common situations: Assets/vfs file unreadable at apply time (permissions, missing file); custom fi.Resource implementations whose Read errors; transient storage issues when reading from a remote VFS.

Related errors


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