kubernetes/kops · error

error decoding userdata: %s

Error message

error decoding userdata: %s

What it means

Find() decodes the UserData stored in an existing EC2 Launch Template from base64 into raw user data. EC2 stores UserData base64-encoded; this error means that stored value could not be decoded, which indicates corrupted or non-base64 data in the launch template. The Find operation aborts so the actual state cannot be compared with the desired state.

Source

Thrown at upup/pkg/fi/cloudup/awstasks/launchtemplate_target_api.go:312

			actual.RootVolumeType = b.Ebs.VolumeType
			actual.RootVolumeIops = b.Ebs.Iops
			actual.RootVolumeThroughput = b.Ebs.Throughput
			actual.RootVolumeEncryption = b.Ebs.Encrypted
			if b.Ebs.KmsKeyId != nil {
				actual.RootVolumeKmsKey = b.Ebs.KmsKeyId
			} else {
				actual.RootVolumeKmsKey = new("")
			}
		} else {
			_, d := BlockDeviceMappingFromLaunchTemplateBootDeviceRequest(b)
			actual.BlockDeviceMappings = append(actual.BlockDeviceMappings, d)
		}
	}

	if lt.LaunchTemplateData.UserData != nil {
		ud, err := base64.StdEncoding.DecodeString(aws.ToString(lt.LaunchTemplateData.UserData))
		if err != nil {
			return nil, fmt.Errorf("error decoding userdata: %s", err)
		}
		actual.UserData = fi.NewStringResource(string(ud))
	}

	// @step: add tags
	if len(lt.LaunchTemplateData.TagSpecifications) > 0 {
		ts := lt.LaunchTemplateData.TagSpecifications[0]
		if ts.Tags != nil {
			tags := mapEC2TagsToMap(ts.Tags)
			actual.Tags = tags
		}
	}

	// @step: add instance metadata options
	if options := lt.LaunchTemplateData.MetadataOptions; options != nil {
		actual.HTTPPutResponseHopLimit = options.HttpPutResponseHopLimit
		if len(options.HttpTokens) > 0 {
			actual.HTTPTokens = new(options.HttpTokens)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the launch template's UserData in the AWS console and re-encode it as base64
  2. Let kOps recreate the launch template (kops update cluster --cloud-labels / replace task) so correct userdata is written
  3. Validate any external tooling base64-encodes UserData before CreateLaunchTemplate
  4. Check `echo '<stored>' | base64 -d` locally to confirm corruption

Example fix

// before (external tool)
UserData: string(nodeUpConfig)
// after
UserData: base64.StdEncoding.EncodeToString(nodeUpConfig)
Defensive patterns

Strategy: validation

Validate before calling

raw := aws.ToString(lt.LaunchTemplateData.UserData)
if _, err := base64.StdEncoding.DecodeString(raw); err != nil {
  return fmt.Errorf("launch template %s has non-base64 userdata", name)
}

Type guard

func isBase64(s string) bool {
  _, err := base64.StdEncoding.DecodeString(s)
  return err == nil
}

Try / catch

ud, err := base64.StdEncoding.DecodeString(raw)
if err != nil {
  return nil, fmt.Errorf("error decoding userdata for %s (recreate the launch template): %w", name, err)
}

Prevention

When it happens

Trigger: lt.LaunchTemplateData.UserData is non-nil but its string is not valid base64 (e.g. manually edited launch template with plaintext UserData, or data corrupted by external tooling).

Common situations: Someone modified the launch template via AWS console/packer and supplied unencoded userdata; custom automation writing UserData without base64 encoding; data corruption from copy-paste.

Related errors


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