AWS Security Hub · ELB
ELB.9: CLBs should have cross-zone balancing
Written and reviewed by Emnode · Last reviewed
What does AWS Security Hub ELB.9 check?
ELB.9 fails when a Classic Load Balancer has cross-zone load balancing disabled. With it off, each CLB node distributes traffic only to targets in its own Availability Zone.
Why does ELB.9 matter?
Without cross-zone balancing, traffic is split evenly per node rather than per instance, so a zone with fewer healthy targets gets the same share as a busy one — leading to lopsided load, hot instances and over-provisioning to compensate. Enabling it spreads requests evenly across all registered targets. This is one of the rare findings where the compliance fix and a real cost saving are the same single action.
How do I fix ELB.9?
- Audit CLBs and check the CrossZoneLoadBalancing attribute with describe-load-balancer-attributes.
- Enable it with modify-load-balancer-attributes; the change propagates with no downtime.
- Confirm targets are now receiving balanced traffic and right-size the fleet down if it was over-provisioned.
- Default cross-zone balancing on in your IaC so new CLBs are compliant.
Remediation script · bash
# Harden every Application Load Balancer in the region: reject invalid headers and
# require defensive (or strictest) desync mode. Both are instant, non-disruptive flips.
for arn in $(aws elbv2 describe-load-balancers \
--query 'LoadBalancers[?Type==`application`].LoadBalancerArn' --output text); do
aws elbv2 modify-load-balancer-attributes --load-balancer-arn "$arn" \
--attributes \
Key=routing.http.drop_invalid_header_fields.enabled,Value=true \
Key=routing.http.desync_mitigation_mode,Value=defensive
echo "$arn: hardened"
done
# Switch load-balanced Auto Scaling groups to ELB health checks with a safe grace period
# (confirm the target-group probe reflects real app health first).
for g in $(aws autoscaling describe-auto-scaling-groups \
--query 'AutoScalingGroups[?(LoadBalancerNames!=`[]` || TargetGroupARNs!=`[]`) && HealthCheckType==`EC2`].AutoScalingGroupName' \
--output text); do
aws autoscaling update-auto-scaling-group --auto-scaling-group-name "$g" \
--health-check-type ELB --health-check-grace-period 300
echo "$g: now using ELB health checks"
done Full walkthrough (console steps, edge cases and verification) in the lesson Harden load balancers (ALB/NLB/CLB).
More ELB controls
- ELB.1 ALB serves HTTP without redirecting to HTTPS
- ELB.2 CLB SSL/HTTPS listeners should use ACM certs
- ELB.3 CLB listeners should use HTTPS/TLS termination
- ELB.4 ALB accepts malformed HTTP headers
- ELB.5 Load balancers are not writing access logs
- ELB.6 Load balancers can be deleted by accident
- ELB.7 CLBs should have connection draining
- ELB.8 CLB SSL listeners should use strong policy
- ELB.10 CLBs should span multiple AZs
- ELB.12 ALB desync mitigation mode
- ELB.13 A single-AZ load balancer is a data-plane single point of failure
- ELB.14 CLB desync mitigation mode