kubernetes/kops · error

reading expected user-data: %w

Error message

reading expected user-data: %w

What it means

In checkUserDataDifferences, the expected user-data (a fi.Resource held by the Instance task) is materialized with fi.ResourceAsBytes before SHA-256 comparison against the live server user-data. This error wraps a failure of that materialization: the resource could not be opened or read (e.g. an unreadable local file or failing resource provider). It indicates the desired user-data on the kOps side is unreadable, not a problem with the cloud.

Source

Thrown at upup/pkg/fi/cloudup/scalewaytasks/instance.go:429

}

func checkUserDataDifferences(c *fi.CloudupContext, cloud scaleway.ScwCloud, actualServer *instance.Server, expectedUserData *fi.Resource) (bool, error) {
	actualUserData, err := cloud.InstanceService().GetServerUserData(&instance.GetServerUserDataRequest{
		Zone:     actualServer.Zone,
		ServerID: actualServer.ID,
		Key:      "cloud-init",
	}, scw.WithContext(c.Context()))
	if err != nil {
		return false, fmt.Errorf("getting actual user-data: %w", err)
	}

	actualUserDataBytes, err := io.ReadAll(actualUserData)
	if err != nil {
		return false, fmt.Errorf("reading actual user-data: %w", err)
	}
	expectedUserDataBytes, err := fi.ResourceAsBytes(*expectedUserData)
	if err != nil {
		return false, fmt.Errorf("reading expected user-data: %w", err)
	}

	if sha256.Sum256(actualUserDataBytes) != sha256.Sum256(expectedUserDataBytes) {
		return true, nil
	}
	return false, nil
}

func imageLabelFromID(c *fi.CloudupContext, cloud scaleway.ScwCloud, id string) (string, error) {
	localImage, err := cloud.MarketplaceService().GetLocalImage(&marketplace.GetLocalImageRequest{
		LocalImageID: id,
	}, scw.WithContext(c.Context()))
	if err != nil {
		return "", fmt.Errorf("getting image from the marketplace: %w", err)
	}
	return localImage.Label, nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check that the source of the user-data resource (bootstrap script path) exists and is readable by the kOps process.
  2. Re-run `kops update cluster`; if a temp file was deleted, it will be regenerated.
  3. Verify file permissions on ~/.cache/kops or the assets directory kOps reads bootstrap scripts from.
  4. If it persists, file an issue — this usually indicates an internal kOps resource construction bug.
Defensive patterns

Strategy: validation

Validate before calling

// validate the expected user-data resource is readable before the reconcile
if expectedUserData != nil {
    if _, err := fi.ResourceAsBytes(*expectedUserData); err != nil {
        return fmt.Errorf("expected user-data unreadable: %w", err)
    }
}

Type guard

func userDataReadable(r fi.Resource) bool {
    if r == nil { return false }
    _, err := fi.ResourceAsBytes(r)
    return err == nil
}

Try / catch

expectedBytes, err := fi.ResourceAsBytes(*expectedUserData)
if err != nil {
    return false, fmt.Errorf("reading expected user-data: %w", err) // surfaces as invalid cluster spec, not a cloud issue
}

Prevention

When it happens

Trigger: fi.ResourceAsBytes(*expectedUserData) errors because the backing resource — typically a file:// resource or a bytes resource from the instance template — cannot be opened/read; file deleted or permissions changed between task construction and rendering.

Common situations: Cluster manifest references user-data generated on the fly (e.g. nodeup bootstrap script) whose underlying file handle or path is unavailable; running kOps in a container without the referenced file mounted; permission-restricted secrets dir.

Related errors


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