This check flags Application Load Balancers that allow malformed HTTP headers to pass through to your backends, opening the door to request smuggling and cache poisoning. Enable the routing.http.drop_invalid_header_fields.enabled attribute to drop those headers at the edge.
An Application Load Balancer (ALB) sits at the front of your application, terminating connections and forwarding requests to your targets. By default, an ALB is fairly lenient about what it forwards. If a client sends HTTP headers with invalid characters in the field names, the ALB will happily pass them along to your backend instead of rejecting them. The ALB Does Not Drop Invalid Headers check identifies load balancers where this leniency has not been locked down.
Flipping a single attribute closes the gap. The trouble is that it is off by default, so most ALBs created through the console, Terraform, or CloudFormation never have it set unless someone went out of their way to do so.
What this check detects
The check inspects each Application Load Balancer in your account and looks at the routing.http.drop_invalid_header_fields.enabled attribute. If that attribute is set to false (the default), the check fails.
When the attribute is disabled, the ALB forwards HTTP headers whose field names contain characters outside the valid set defined in RFC 7230. That includes things like spaces, control characters, or other non-token characters in header names. When the attribute is enabled, the ALB strips those headers before the request ever reaches your target group.
Note: This setting only affects invalid header field names, not all unusual headers. Standard custom headers like X-Forwarded-For or your own X-Tenant-Id are untouched. The ALB only drops headers that violate the HTTP specification's rules for valid token characters.
Why it matters
Malformed headers are a classic ingredient in HTTP-layer attacks. When two systems in a request chain disagree about how to parse an ambiguous or invalid header, an attacker can exploit that disagreement.
HTTP request smuggling
Request smuggling happens when a front-end proxy and a back-end server interpret the boundaries of an HTTP request differently. Invalid or duplicated headers, particularly around Content-Length and Transfer-Encoding, are a common trigger. If your ALB forwards a header the backend parses in an unexpected way, an attacker can prepend a hidden request to the next user's connection. That can mean stealing session cookies, bypassing authentication, or poisoning responses for other users on the same connection.
Cache poisoning
If you run a CDN or cache behind or in front of the ALB, malformed headers can be used to manipulate cache keys. An attacker who can get a poisoned response stored under a normal cache key affects every user who later requests that resource.
Backend inconsistency
Different application frameworks handle invalid headers in different ways. Some reject the request, some silently drop the header, and some pass it through to application code as-is. That inconsistency is exactly the kind of gap that turns a minor parsing quirk into an exploitable vulnerability. Dropping invalid headers at the load balancer gives you a single, predictable behavior across every backend.
Warning: If a legitimate client or internal service is currently relying on a header with a technically invalid name, enabling this attribute will start silently dropping it. This is rare, but worth checking your application logs before flipping it in production. Valid header names use only letters, digits, and a handful of symbols such as hyphens, so a header named X_Custom Header with a space would get dropped.
How to fix it
The remediation is the same regardless of how you provision your infrastructure: set routing.http.drop_invalid_header_fields.enabled to true.
AWS CLI
First, find the ARN of the load balancer you want to update:
aws elbv2 describe-load-balancers \
--query "LoadBalancers[?Type=='application'].[LoadBalancerName,LoadBalancerArn]" \
--output table
Then modify the attribute:
aws elbv2 modify-load-balancer-attributes \
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-alb/50dc6c495c0c9188 \
--attributes Key=routing.http.drop_invalid_header_fields.enabled,Value=true
Verify the change took effect:
aws elbv2 describe-load-balancer-attributes \
--load-balancer-arn arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-alb/50dc6c495c0c9188 \
--query "Attributes[?Key=='routing.http.drop_invalid_header_fields.enabled']"
Note: This change applies immediately and does not require recreating the load balancer or interrupting active connections. There is no additional cost for enabling it.
AWS Console
- Open the EC2 console and select Load Balancers from the left menu.
- Select your Application Load Balancer.
- Go to the Attributes tab and choose Edit.
- Under Packet handling, enable Drop invalid header fields.
- Save changes.
Terraform
Add the drop_invalid_header_fields argument to your aws_lb resource:
resource "aws_lb" "app" {
name = "my-alb"
internal = false
load_balancer_type = "application"
subnets = var.subnet_ids
security_groups = [aws_security_group.alb.id]
drop_invalid_header_fields = true
}
Run terraform plan to confirm the change is limited to the attribute, then terraform apply.
CloudFormation
Set the attribute under LoadBalancerAttributes:
AppLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: my-alb
Type: application
Scheme: internet-facing
Subnets: !Ref SubnetIds
SecurityGroups:
- !Ref AlbSecurityGroup
LoadBalancerAttributes:
- Key: routing.http.drop_invalid_header_fields.enabled
Value: "true"
How to prevent it from happening again
Fixing one ALB by hand is fine. Making sure the next 50 ALBs ship with the attribute set is what actually moves the needle. Bake the requirement into the layers where infrastructure gets defined and reviewed.
Enforce it in Terraform with a module default
If your teams provision ALBs through a shared internal module, set drop_invalid_header_fields = true as the default inside the module. Individual teams then get the secure setting without thinking about it, and you only override in the rare cases where it is genuinely needed.
Add a policy-as-code gate
Catch misconfigured ALBs before they merge using a tool like Checkov, tfsec, or OPA/Conftest in your CI pipeline. Here is a Conftest policy in Rego that fails any plan creating an ALB without the attribute:
package main
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_lb"
resource.change.after.load_balancer_type == "application"
not resource.change.after.drop_invalid_header_fields
msg := sprintf("ALB '%s' must set drop_invalid_header_fields = true", [resource.address])
}
Wire that into your pull request checks against a terraform plan -out JSON export so the build fails before anything reaches AWS.
Tip: Checkov already ships a built-in rule for this (CKV_AWS_131). Adding checkov -d . to your CI run gives you coverage for this check plus a few hundred others with no custom code to maintain.
Detect drift continuously
Policy gates only catch resources that go through your pipeline. Anything created manually, by another team, or in a forgotten account slips through. Continuous monitoring with Lensix scans your live AWS environment and flags any ALB where the attribute is disabled, so a console-clicked load balancer does not quietly sit exposed for months.
Best practices
- Enable it on every ALB by default. There is no cost and almost no downside. Treat it as a baseline setting, not an opt-in feature.
- Pair it with other ALB hardening attributes. Set
routing.http.desync_mitigation_modetodefensiveorstrictestto further reduce request smuggling exposure, and enablerouting.http.x_amzn_tls_version_and_cipher_suite.enabledif you need TLS visibility downstream. - Use HTTP/2 and modern listeners. Keep your ALB on current TLS policies and avoid legacy ciphers, since header-based attacks often pair with weak transport security.
- Layer your defenses. Dropping invalid headers at the ALB is one control. AWS WAF in front of the ALB gives you rule-based filtering for known smuggling and injection patterns. Defense in depth matters because no single control catches everything.
- Audit existing ALBs in bulk. Run a one-time inventory across all regions and accounts to find the load balancers that predate your policy gate, then remediate them in a single pass.
This is one of the cheaper security wins available in AWS. A single attribute, no downtime, no cost, and it closes off a category of attacks that are genuinely hard to detect once they are in flight. Set it once in your modules, gate it in CI, and monitor for drift, and you can stop thinking about it.

