Cloud and CDN

How to add HTTPS to an AWS Application Load Balancer with ACM

By · Last verified

An Application Load Balancer (ALB) serves HTTPS with a free ACM certificate: request the certificate with DNS validation, attach it to a port-443 listener and redirect port 80 to HTTPS. ACM then renews the certificate without your involvement.

Commands use the AWS CLI v2 and reflect ACM and Elastic Load Balancing as of November 2026. The console offers the same steps.

Prerequisites

The ALB and its target group should already serve your application over HTTP.

  • AWS CLI v2 configured with permissions for ACM and Elastic Load Balancing (aws sts get-caller-identity works).
  • An internet-facing ALB, its target group, and their ARNs; a security group allowing inbound 80 and 443.
  • Access to the domain's DNS (Route 53 or another provider) to add a CNAME and point example.com at the ALB.
  • CAA records, if you use them, that allow Amazon (amazon.com, amazontrust.com, awstrust.com or amazonaws.com); check with the CAA checker.

Step 1: Request the certificate

Request the certificate in the ALB's region, because a listener can only use an ACM certificate from its own region:

export AWS_REGION=eu-west-1
CERT_ARN=$(aws acm request-certificate \
  --domain-name example.com \
  --subject-alternative-names www.example.com \
  --validation-method DNS \
  --key-algorithm EC_prime256v1 \
  --query CertificateArn --output text)
echo "$CERT_ARN"

EC_prime256v1 requests an ECDSA key; use RSA_2048 if old clients must connect.

Step 2: Create the DNS validation records

ACM validates each name through a CNAME record. Print the records it expects:

aws acm describe-certificate --certificate-arn "$CERT_ARN" \
  --query 'Certificate.DomainValidationOptions[].ResourceRecord' --output table

Create each CNAME at your DNS provider (in the Route 53 console, the certificate page offers Create records in Route 53). Then wait:

aws acm wait certificate-validated --certificate-arn "$CERT_ARN"

Step 3: Add the HTTPS listener

The port-443 listener presents the certificate and forwards to the target group. The ELBSecurityPolicy-TLS13-1-2-2021-06 policy allows TLS 1.3 and 1.2:

ALB_ARN=arn:aws:elasticloadbalancing:eu-west-1:111122223333:loadbalancer/app/web/0123456789abcdef
TG_ARN=arn:aws:elasticloadbalancing:eu-west-1:111122223333:targetgroup/web/0123456789abcdef
aws elbv2 create-listener --load-balancer-arn "$ALB_ARN" \
  --protocol HTTPS --port 443 \
  --certificates CertificateArn="$CERT_ARN" \
  --ssl-policy ELBSecurityPolicy-TLS13-1-2-2021-06 \
  --default-actions Type=forward,TargetGroupArn="$TG_ARN"

Replace the ARNs with yours (aws elbv2 describe-load-balancers and describe-target-groups list them).

Step 4: Redirect HTTP to HTTPS and point DNS at the ALB

Change the port-80 listener's default action to a redirect (create it if it does not exist):

HTTP_LISTENER_ARN=$(aws elbv2 describe-listeners --load-balancer-arn "$ALB_ARN" \
  --query 'Listeners[?Port==`80`].ListenerArn' --output text)
aws elbv2 modify-listener --listener-arn "$HTTP_LISTENER_ARN" \
  --default-actions 'Type=redirect,RedirectConfig={Protocol=HTTPS,Port=443,StatusCode=HTTP_301}'

Then point example.com (Route 53 alias record) and www.example.com (alias or CNAME) at the ALB's DNS name.

Verify

The endpoint should present the Amazon-issued certificate, and HTTP should return a 301 to HTTPS. Check it with the SSL checker, or from any terminal:

curl ssl.sh/example.com
curl -sI http://example.com | grep -iE '^(HTTP|location)'

In AWS:

aws acm describe-certificate --certificate-arn "$CERT_ARN" --query 'Certificate.[Status,InUseBy,NotAfter]'

Automatic renewal

ACM renews DNS-validated public certificates automatically while two conditions hold: the certificate is associated with an AWS service such as this ALB, and the validation CNAME records stay in DNS. The ARN does not change, so the listener picks up the renewed certificate without any change. Check the status at any time:

aws acm describe-certificate --certificate-arn "$CERT_ARN" --query 'Certificate.RenewalSummary'

Imported certificates are never renewed by ACM. Public certificate lifetimes are capped by the CA/Browser Forum (200 days since March 15, 2026, 47 days from March 15, 2029), so ACM will renew more often; that is automatic as long as the CNAMEs remain. Add the domain to ssl.sh monitoring (in development) as an external check.

Troubleshooting

  • Status stays PENDING_VALIDATION: the CNAME is missing or has a doubled zone name; compare with describe-certificate output.
  • CAA_ERROR or failed validation: a CAA record excludes Amazon; see CAA record prevents issuance.
  • Certificate not listed when creating the listener: it was requested in another region.
  • Browsers show a name mismatch: the requested name is not on the certificate or DNS points at another load balancer; see NET::ERR_CERT_COMMON_NAME_INVALID.
  • Old clients fail the handshake: the TLS 1.3/1.2 policy or ECDSA key excludes them; see ERR_SSL_VERSION_OR_CIPHER_MISMATCH.

FAQ

Why is my ACM certificate stuck in Pending validation?

ACM cannot find the validation CNAME. Check that you created the exact record name and value from describe-certificate; some DNS providers append the zone name automatically, which doubles the domain. Also check CAA records allow Amazon.

Can I use an ACM certificate on an EC2 instance directly?

Not a standard ACM public certificate, because its private key cannot be exported. Terminate TLS on the load balancer, use the paid exportable ACM certificate type, or run an ACME client such as Certbot on the instance.

How do I add a second domain to the same ALB?

Request another ACM certificate and add it to the HTTPS listener with aws elbv2 add-listener-certificates; the ALB selects the certificate by SNI. Keep one default certificate on the listener.

Sources

  1. AWS Certificate Manager: DNS validation
  2. AWS Certificate Manager: Managed certificate renewal
  3. AWS Certificate Manager: Public certificates
  4. Elastic Load Balancing: Create an HTTPS listener
  5. Elastic Load Balancing: Security policies