You're trying to create an Amazon Machine Image (AMI) from your EC2 instance and encountering errors like:

bash
Failed to create AMI: InvalidInstanceID.NotFound

Or:

bash
IncorrectInstanceState: The instance 'i-1234567890abcdef0' is not in a valid state for this operation.

AMI creation failures can block deployments and backups. Here's how to fix them.

Understanding AMI Creation

Creating an AMI involves:

  1. 1.Creating snapshots of all EBS volumes attached to the instance
  2. 2.Registering the AMI with the snapshot IDs
  3. 3.Registering the AMI metadata

Any failure in this process leaves partial artifacts. Understanding this helps troubleshooting.

Solution 1: Fix Instance State Issues

The instance must be in a valid state for AMI creation:

bash
# Check instance state
aws ec2 describe-instances \
    --instance-ids i-1234567890abcdef0 \
    --query 'Reservations[0].Instances[0].[InstanceId,State.Name,State.Code]' \
    --output table

Valid states for AMI creation: - running - Live instance (requires reboot by default) - stopped - Ideal state for consistent AMI - pending - Invalid, wait until running - stopping - Invalid, wait until stopped - shutting-down - Invalid, instance terminating - terminated - Invalid, instance gone

For the cleanest AMI, stop the instance first:

```bash # Stop the instance for consistent AMI aws ec2 stop-instances --instance-ids i-1234567890abcdef0

# Wait for it to stop aws ec2 wait instance-stopped --instance-ids i-1234567890abcdef0

# Create AMI aws ec2 create-image \ --instance-id i-1234567890abcdef0 \ --name "my-ami-$(date +%Y%m%d-%H%M%S)" \ --description "Production AMI" \ --no-reboot

# Start the instance again aws ec2 start-instances --instance-ids i-1234567890abcdef0 ```

Solution 2: Handle No Reboot Option

The --no-reboot flag prevents instance reboot but may cause filesystem inconsistency:

```bash # With reboot (consistent but causes downtime) aws ec2 create-image \ --instance-id i-1234567890abcdef0 \ --name "my-ami-consistent" \ --description "Consistent AMI with reboot"

# Without reboot (no downtime but potential inconsistency) aws ec2 create-image \ --instance-id i-1234567890abcdef0 \ --name "my-ami-no-reboot" \ --no-reboot ```

If you get filesystem corruption with --no-reboot:

```bash # Sync filesystem first (inside the instance) ssh ec2-user@instance-ip "sudo sync && sudo fsfreeze -f /"

# Then create AMI aws ec2 create-image --instance-id i-1234567890abcdef0 --name "my-ami" --no-reboot

# Unfreeze after (if needed) ssh ec2-user@instance-ip "sudo fsfreeze -u /" ```

Solution 3: Verify Instance Store vs EBS

AMI creation only works consistently with EBS-backed instances:

bash
# Check root device type
aws ec2 describe-instances \
    --instance-ids i-1234567890abcdef0 \
    --query 'Reservations[0].Instances[0].[RootDeviceType,RootDeviceName,BlockDeviceMappings]' \
    --output json
  • RootDeviceType: ebs - AMI creation works normally
  • RootDeviceType: instance-store - Cannot create AMI directly

For instance-store instances, you need to bundle the volume:

```bash # This only works for instance-store # Inside the instance: sudo ec2-bundle-vol -d /mnt -k /path/to/pk.pem -c /path/to/cert.pem -u 123456789012 -s 10240

# Upload to S3 ec2-upload-bundle -b my-bucket -m /mnt/image.manifest.xml -a AKIAIOSFODNN7EXAMPLE -s wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY ```

Better solution: Convert to EBS-backed instance first.

Solution 4: Fix Permission Issues

AMI creation requires specific IAM permissions:

bash
# Test your permissions
aws ec2 create-image \
    --instance-id i-1234567890abcdef0 \
    --name "test-permissions" \
    --dry-run

Required IAM policy:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CreateImage",
        "ec2:DescribeInstances",
        "ec2:DescribeImages",
        "ec2:CreateSnapshot",
        "ec2:CreateTags",
        "ec2:RegisterImage"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "kms:CreateGrant",
        "kms:Decrypt",
        "kms:DescribeKey",
        "kms:Encrypt",
        "kms:GenerateDataKey*",
        "kms:ReEncrypt*"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "kms:ViaService": "ec2.amazonaws.com"
        }
      }
    }
  ]
}

Solution 5: Handle Encrypted Volumes

If your instance has encrypted volumes, AMI creation requires KMS access:

bash
# Check for encrypted volumes
aws ec2 describe-instances \
    --instance-ids i-1234567890abcdef0 \
    --query 'Reservations[0].Instances[0].BlockDeviceMappings[*].[DeviceName,Ebs.Encrypted,Ebs.KmsKeyId]' \
    --output table

If encrypted, ensure you have KMS permissions and the key is not scheduled for deletion:

```bash # Verify KMS key status aws kms describe-key --key-id alias/my-ebs-key --query 'KeyMetadata.[KeyId,KeyState,KeyManager]'

# Key must be in "Enabled" state, not "PendingDeletion" or "Disabled" ```

Solution 6: Clean Up Failed AMI Creations

Failed AMI creation leaves orphaned snapshots:

```bash # List your AMIs and their snapshots aws ec2 describe-images \ --owners self \ --query 'Images[*].[ImageId,Name,BlockDeviceMappings[*].Ebs.SnapshotId]' \ --output table

# List all snapshots aws ec2 describe-snapshots \ --owner-ids self \ --query 'Snapshots[*].[SnapshotId,Description,StartTime,VolumeId]' \ --output table ```

To clean up a failed AMI:

```bash # First deregister the AMI (if partially created) aws ec2 deregister-image --image-id ami-1234567890abcdef0

# Then delete orphaned snapshots aws ec2 delete-snapshot --snapshot-id snap-1234567890abcdef0 ```

Solution 7: Check AMI Limits

You might have hit your AMI quota:

```bash # Check AMI limit aws service-quotas get-service-quota \ --service-code ec2 \ --quota-code L-355B2B67 \ --region us-east-1 \ --query 'Quota.Value'

# Count your current AMIs aws ec2 describe-images \ --owners self \ --query 'length(Images)' ```

Request increase if needed:

bash
aws service-quotas request-service-quota-increase \
    --service-code ec2 \
    --quota-code L-355B2B67 \
    --desired-value 100 \
    --region us-east-1

Solution 8: Verify Snapshot Completion

AMI creation fails if snapshots don't complete:

```bash # Create AMI and capture the image ID image_id=$(aws ec2 create-image \ --instance-id i-1234567890abcdef0 \ --name "my-ami-$(date +%Y%m%d)" \ --query 'ImageId' \ --output text)

# Wait for AMI to be available (includes waiting for snapshots) aws ec2 wait image-available --image-ids $image_id

# Check AMI status aws ec2 describe-images \ --image-ids $image_id \ --query 'Images[0].[ImageId,State,BlockDeviceMappings[*].Ebs.SnapshotId]' ```

Verification

After creating an AMI, verify it's usable:

```bash # Check AMI details aws ec2 describe-images \ --image-ids ami-1234567890abcdef0 \ --query 'Images[0].[ImageId,Name,State,CreationDate,RootDeviceType,BlockDeviceMappings[*].DeviceName]' \ --output table

# Test launch from AMI aws ec2 run-instances \ --image-id ami-1234567890abcdef0 \ --instance-type t3.micro \ --key-name my-key-pair \ --subnet-id subnet-12345 ```

Complete AMI Creation Script

```bash #!/bin/bash

INSTANCE_ID="i-1234567890abcdef0" AMI_NAME="production-$(date +%Y%m%d-%H%M%S)" AMI_DESCRIPTION="Production AMI created from $INSTANCE_ID"

# Stop instance for consistency echo "Stopping instance $INSTANCE_ID..." aws ec2 stop-instances --instance-ids $INSTANCE_ID aws ec2 wait instance-stopped --instance-ids $INSTANCE_ID

# Create AMI echo "Creating AMI..." IMAGE_ID=$(aws ec2 create-image \ --instance-id $INSTANCE_ID \ --name "$AMI_NAME" \ --description "$AMI_DESCRIPTION" \ --no-reboot \ --tag-specifications 'ResourceType=image,Tags=[{Key=Name,Value='"$AMI_NAME"'},{Key=SourceInstance,Value='"$INSTANCE_ID"'}]' \ --query 'ImageId' \ --output text)

echo "AMI creation initiated: $IMAGE_ID"

# Wait for completion echo "Waiting for AMI to be available..." aws ec2 wait image-available --image-ids $IMAGE_ID

# Restart instance echo "Starting instance $INSTANCE_ID..." aws ec2 start-instances --instance-ids $INSTANCE_ID

# Verify AMI echo "AMI created successfully:" aws ec2 describe-images \ --image-ids $IMAGE_ID \ --query 'Images[0].[ImageId,Name,State,BlockDeviceMappings[*].Ebs.SnapshotId]' \ --output table ```

Common Error Messages Reference

ErrorCauseSolution
InvalidInstanceID.NotFoundWrong instance IDVerify instance exists
IncorrectInstanceStateInstance pending/stoppingWait or stop instance first
InvalidInstanceID.NotSupportedInstance-store rootConvert to EBS first
UnauthorizedOperationMissing permissionsAdd EC2 CreateImage permission
ResourceLimitExceededAMI quota reachedRequest quota increase
InvalidAMIName.DuplicateName already usedUse unique name
Kms.NotFoundKMS key deletedRestore key or decrypt volume
SnapshotInUseSnapshot conflictWait and retry