---
cuppy_hub: aws
cuppy_path: reference/elb/errors.md
cuppy_section: docs
cuppy_doc: NPAD-6HHW
cuppy_doc_uuid: b7deb1ce-1f92-45fd-99dc-262d8549e6da
cuppy_permalink: https://cuppy.io/aws/d/NPAD-6HHW
cuppy_version: 4
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/aws/docs/reference/elb/errors
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: a82b334001aadcecd04cb84de865cc1374d00533c0ea8b82b72b8381c2120cbf
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Application Load Balancer errors and target health reason codes

**The load balancer generates the statuses below itself and counts them in `HTTPCode_ELB_4XX_Count` / `HTTPCode_ELB_5XX_Count`.** Statuses your targets return are passed through and counted in `HTTPCode_Target_*`. For those, read the application's logs.

## Load balancer–generated statuses

**Check for every row:** find the request in the access log (`aws elbv2 describe-load-balancer-attributes --load-balancer-arn <lb>` → `access_logs.s3.*` says whether and where logging is on). `elb_status_code` with `target_status_code` `-` means the load balancer produced the status; `error_reason` names the cause for authentication, Lambda and WAF failures. Metrics: `HTTPCode_ELB_4XX_Count`/`5XX` against `HTTPCode_Target_*` (`guides/elb/fix-alb-5xx.md`).

| Status | Causes → fix |
|---|---|
| **400** | Malformed request; request line or single header over 16 KB, or all headers over 64 KB; client closed before sending the full body. Also requests blocked as *Severe* by desync mitigation |
| **401** | Listener authentication: the IdP denied access or `OnUnauthenticatedRequest` is `deny`; claims too large; HTTP/1.0 without a Host header; the scope returns no ID token; login timeout. JWT verification: `JWTHeaderNotPresent`, `JWTRequestFormatInvalid`, `JWTSignatureValidationFailed`, `JWTClaimNotPresent`, `JWTClaimFormatInvalid` |
| **403** | An AWS WAF web ACL blocked the request |
| **405** | `TRACE` method (not supported) |
| **408** | The client sent no data within the idle timeout. TCP keep-alives don't count: send at least 1 byte, or raise the idle timeout |
| **413** | Lambda target and request body over 1 MB; or the header limits above |
| **414** | URL or query string too long |
| **460** | The client closed the connection before the idle timeout elapsed. The client's own timeout is shorter than the request takes |
| **463** | `X-Forwarded-For` with more than 30 IP addresses |
| **464** | Protocol mismatch with the target group's protocol version: HTTP/1.1 request to a gRPC or HTTP/2 group, gRPC to HTTP/1.1, non-POST HTTP/2 to gRPC |
| **500** | WAF rule execution error; can't reach the IdP token/userinfo or JWKS endpoint (DNS, egress security group or NACL, no internet for an internal load balancer: add NAT); IdP or JWKS slower than 5 s; claims over 11 KB; JWKS over 150 KB or more than 10 keys; target optimizer agent error |
| **501** | `Transfer-Encoding` other than `chunked`/`identity`; WebSocket to a target-optimizer group |
| **502** | TCP RST from the target on connect; ICMP unreachable; the target closed a connection with a request outstanding (**keep-alive shorter than the idle timeout**); malformed response or headers over 32 KB; deregistration delay elapsed; Lambda response over 1 MB, timeout, error or throttle; TLS handshake error to the target. See `guides/elb/fix-alb-5xx.md` |
| **503** | No registered targets, or all targets `unused`; target optimizer has no ready targets |
| **504** | No connection within 10 s; no response within the idle timeout; NACL blocks ephemeral ports 1024–65535 from targets back to the load balancer; `Content-Length` larger than the body; Lambda didn't respond before the connection timeout; TLS handshake to the target over 10 s |
| **505** | HTTP version mismatch on an established connection |
| **507** | Redirect URL too long |
| **561** | The IdP returned an error during authentication. See the access log's error reason code |
| **562** | The JWKS endpoint returned non-2xx or an invalid key set (format, algorithm, key not convertible, key size not 2K) |
| **000** | HTTP/2 connection closed with GOAWAY after 10,000 requests. The client should reconnect |

## Target health reason codes

Run `aws elbv2 describe-target-health --target-group-arn <tg>`. `Elb.*` codes come from the load balancer side and `Target.*` from the target side.

**Check for every row:** `aws elbv2 describe-target-health --target-group-arn <tg> --query 'TargetHealthDescriptions[].[Target.Id,TargetHealth.State,TargetHealth.Reason,TargetHealth.Description]'`.

| Reason | State | Meaning → fix |
|---|---|---|
| `Elb.RegistrationInProgress` | initial | Registering. Wait |
| `Elb.InitialHealthChecking` | initial | It must pass **one** check first. Wait |
| `Elb.InternalError` | unhealthy | `Health checks failed due to an internal error` on the load balancer side; if it persists, open a support case (UNVERIFIED remedy) |
| `Target.ResponseCodeMismatch` | unhealthy | `Health checks failed with these codes: [code]`. The path returned something outside the matcher (default `200`). Fix the path, or widen `Matcher` (e.g. `200-399`). A `301`/`302` often means the app redirects HTTP to HTTPS or demands a Host name: the check's `Host` header is the target's **private IP** (with `:port` for non-default ports) |
| `Target.Timeout` | unhealthy | `Request timed out`. Security group or NACL blocks the health-check port, the target is overloaded, or the path is slow (timeout default 5 s) |
| `Target.FailedHealthChecks` | unhealthy | Not listening on the health-check port, or the app is down |
| `Target.NotRegistered` | unused | Not registered to this target group |
| `Target.NotInUse` | unused | No listener rule uses the target group, or the target's AZ isn't enabled on the load balancer |
| `Target.InvalidState` | unused | The instance is stopped or terminated |
| `Target.IpUnusable` | unused | The IP belongs to a load balancer |
| `Target.DeregistrationInProgress` | draining | Draining connections |
| `Target.HealthCheckDisabled` | unavailable | Health checks are off for the group |

Health checks send `GET`s with `User-Agent: ELB-HealthChecker/2.0`. They don't support WebSockets.

## Symptoms without a status

| Symptom | Cause → fix | Check |
|---|---|---|
| Internet-facing load balancer never answers | It's attached to **private** subnets: it needs public subnets routed to an IGW. Or its security group or NACL doesn't admit clients on the listener port. Or VPC Block Public Access is on | `aws elbv2 describe-load-balancers --names <lb> --query 'LoadBalancers[0].[Scheme,AvailabilityZones[].SubnetId,SecurityGroups]'`, then each subnet's route table for `0.0.0.0/0` → `igw-` |
| Custom domain doesn't reach the load balancer | DNS doesn't resolve to its addresses. Compare `dig <domain>` with `dig <lb DNS name>`, and use an alias record (`guides/route53/point-domain-at-aws.md`) | The two `dig` calls in the cell |
| Browser: `NET::ERR_CERT_COMMON_NAME_INVALID` | The domain isn't on the listener's certificate, or the client used the load balancer's default DNS name: no public certificate can be issued for `*.amazonaws.com` | `aws elbv2 describe-listener-certificates --listener-arn <l>`, then `aws acm describe-certificate --certificate-arn <c> --query Certificate.SubjectAlternativeNames` |
| Certificate unavailable for the listener | The ACM certificate is still `Pending Validation`. Complete DNS or email validation | `aws acm describe-certificate --certificate-arn <c> --query Certificate.Status` |
| Multi-line headers mangled | Not supported: the load balancer inserts `:` | Send the same request with the header on one line |
| High `request_processing_time` on POSTs | Expected with AWS WAF attached: upload time is counted there (otherwise in `target_processing_time`) | `aws wafv2 get-web-acl-for-resource --resource-arn <lb-arn>` |

## When none of these fits

Turn on access logs and find the request. The ELB status code with the target's status code says which side answered. A missing target status means the target never replied. Check target health reasons (`aws elbv2 describe-target-health`) and the target's own logs. If targets are healthy and logs are clean, test the target directly from inside the VPC (`guides/vpc/diagnose-connection-timeout.md`).


---
<!-- cuppy -->
You are reading one file. The same content is free over MCP at https://cuppy.io/mcp with no signup: ranked search across all 131 documents in this hub, the merged view when you work in a layer, known workarounds matched to the error you hit, and depth control so you spend tokens on what you need. Start with the `_hello` tool. How to connect: https://cuppy.io/aws/ Something wrong in this document? Report it with the `session feedback` tool on the same endpoint.
<!-- /cuppy -->
