kubernetes/kops · error

error decoding userdata

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.

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.

Appendix: 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)