User-data scripts is not running on my custom AMI, but working in standard Amazon linux
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
When user-data works on a standard Amazon Linux AMI but not on your custom AMI, the most likely issue is not the script text itself. The custom image often differs in one of three critical ways: cloud-init is missing or disabled, first-boot state was baked into the AMI, or the script is failing silently at boot. The fix is to verify the boot pipeline, not just the shell commands inside the script.
User Data Usually Runs Through cloud-init
On Amazon Linux images, user-data processing is typically handled by cloud-init. When an EC2 instance starts, cloud-init reads instance metadata, parses user data, and executes supported directives during the boot process.
That means a custom AMI can break user-data execution even if the script is valid, simply by changing the boot-time services or by preserving stale instance state from the machine that was used to create the image.
First Check Whether cloud-init Exists and Is Enabled
Start by confirming that the derived instance actually has the service installed and enabled.
If those services are missing, disabled, or failing at boot, user data will not run the way it did on the stock image.
Also inspect the configuration files.
A custom AMI may include modified cloud-init settings that skip expected modules.
The Most Common Custom-AMI Mistake: Baking Old Instance State Into the Image
A very common failure happens when you create an AMI from an instance that has already completed its first-boot initialization. cloud-init stores state under /var/lib/cloud/. If that state is left in place when the image is created, new instances launched from the AMI may believe first-boot tasks have already run.
Before creating the AMI, clean that state on the source instance.
Then stop the instance and create the AMI. This is often the difference between a reusable image and an image that silently skips user data.
Read the Right Logs
Do not debug this blind. The boot logs usually tell you exactly where the failure occurred.
Look for:
- syntax errors in the script
- a missing interpreter in the shebang line
- package manager failures
- metadata access errors
- a message showing that
cloud-initconsidered initialization already complete
If the logs are empty, that is itself a clue that the service did not run.
Make the Script Self-Diagnosing
A short user-data script with explicit logging is much easier to debug than a large bootstrap file with no output redirection.
If this minimal script does not produce /var/log/user-data-debug.log, the problem is the boot mechanism, not your application setup.
Confirm the AMI Still Matches the Expected Runtime
A custom AMI can diverge from standard Amazon Linux in subtle ways.
Examples include:
- replacing the default shell or removing
/bin/bash - disabling networking too early in boot
- changing systemd targets or service ordering
- hardening metadata access in a way that blocks instance initialization
That is why comparing packages and enabled services between the stock AMI and the custom AMI is often worthwhile.
Retest With a Minimal Launch Template
If the custom image still fails, reduce the launch configuration complexity.
Use:
- a minimal user-data script
- default networking
- no extra bootstrap tooling
- no dependency on external package repositories
Once the minimal case works, add your real setup back one piece at a time. This isolates whether the problem is in the AMI, the user data, or the surrounding infrastructure.
Common Pitfalls
- Assuming the script text is wrong when
cloud-initnever ran at all. - Creating the AMI without cleaning
/var/lib/cloud/first. - Checking only the EC2 console output and ignoring
cloud-initlogs on the instance. - Using a user-data script without a shebang line or without explicit logging.
- Making custom OS changes that disable or reorder the services responsible for first-boot initialization.
Summary
- User-data on Amazon Linux usually depends on
cloud-init. - Custom AMIs often fail because
cloud-initis disabled, misconfigured, or carrying old first-boot state. - Clean
cloud-initstate before creating a reusable AMI. - Debug with
/var/log/cloud-init.log,/var/log/cloud-init-output.log, and a minimal logged script. - If a stock AMI works and the custom one does not, inspect the image boot pipeline before rewriting the user-data script.

