kubernetes/kops · error

Instance UserData was too large (%d bytes)

Error message

Instance UserData was too large (%d bytes)

What it means

EC2 limits UserData to MaxUserDataSize (16 KiB for RunInstances). RenderAWS reads the full UserData and, before encoding it into the RunInstances request, rejects anything larger. The gzip workaround is intentionally disabled because it breaks the AWS console, so oversized UserData is a hard failure and no instance is created.

Source

Thrown at upup/pkg/fi/cloudup/awstasks/instance.go:281

			request.BlockDeviceMappings = []ec2types.BlockDeviceMapping{}
			for deviceName, bdm := range blockDeviceMappings {
				request.BlockDeviceMappings = append(request.BlockDeviceMappings, bdm.ToEC2(deviceName))
			}
		}

		if e.UserData != nil {
			d, err := fi.ResourceAsBytes(e.UserData)
			if err != nil {
				return fmt.Errorf("error rendering Instance UserData: %v", err)
			}
			if len(d) > MaxUserDataSize {
				// TODO: Re-enable gzip?
				// But it exposes some bugs in the AWS console, so if we can avoid it, we should
				//d, err = fi.GzipBytes(d)
				//if err != nil {
				//	return fmt.Errorf("error while gzipping UserData: %v", err)
				//}
				return fmt.Errorf("Instance UserData was too large (%d bytes)", len(d))
			}
			request.UserData = aws.String(base64.StdEncoding.EncodeToString(d))
		}

		if e.IAMInstanceProfile != nil {
			request.IamInstanceProfile = &ec2types.IamInstanceProfileSpecification{
				Name: e.IAMInstanceProfile.Name,
			}
		}

		response, err := t.Cloud.EC2().RunInstances(ctx, request)
		if err != nil {
			return fmt.Errorf("error creating Instance: %v", err)
		}

		e.ID = response.Instances[0].InstanceId
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Shrink the UserData script: remove comments/whitespace or split into multiple smaller scripts.
  2. Move heavy work off UserData: download and run a bootstrap script from S3/HTTPS instead of inlining it.
  3. Use kOps' built-in nodeup bootstrap (default) rather than custom full-script UserData.
  4. Enable/configure the gzip path locally (fi.GzipBytes) if console rendering is not a concern for you.
  5. Check `wc -c` on the rendered script and re-run kops update after trimming.

Example fix

// before (RenderAWS path)
if len(d) > MaxUserDataSize {
	return fmt.Errorf("Instance UserData was too large (%d bytes)", len(d))
}
// after (consumer-side shrink: fetch script instead of inline)
// user-data:
//   #!/bin/sh
//   curl -sSf https://s3.amazonaws.com/my-bucket/bootstrap.sh | bash
Defensive patterns

Strategy: validation

Validate before calling

// Check rendered UserData size before applying
const maxUserDataSize = 16384 // EC2 RunInstances limit used by kOps

func validateUserData(scriptPath string) error {
	d, err := os.ReadFile(scriptPath)
	if err != nil {
		return err
	}
	if len(d) > maxUserDataSize {
		return fmt.Errorf("Instance UserData was too large (%d bytes); max is %d", len(d), maxUserDataSize)
	}
	return nil
}

Try / catch

err := applyCluster(ctx)
if err != nil && strings.Contains(err.Error(), "UserData was too large") {
	return fmt.Errorf("shrink or externalize the bootstrap script, then re-run: %w", err)
}
return err

Prevention

When it happens

Trigger: Creating an EC2 instance whose rendered UserData byte length exceeds MaxUserDataSize (16384 bytes), typically a large bootstrap script or embedded nodeup payload.

Common situations: Very large cluster bootstrap scripts; embedding manifests/configs directly in UserData; multi-line shell scripts grown by repeated edits; region/config changes that balloon generated scripts; accidentally inlining a binary or large config into the igconfig userData field.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


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