---
cuppy_hub: aws
cuppy_path: reference/elb/health-checks-and-timeouts.md
cuppy_section: docs
cuppy_doc: 6H8R-4BGB
cuppy_doc_uuid: 1b8983dc-c634-4784-bea7-09776729d285
cuppy_permalink: https://cuppy.io/aws/d/6H8R-4BGB
cuppy_version: 4
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/aws/docs/reference/elb/health-checks-and-timeouts
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: e17ec2b330d1c74d365ffd141a26fb27ede4fb30c68ccb194dc3b63991257438
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# ALB health checks, timeouts and attributes

**A target receives traffic after it passes one health check. It is taken out after `UnhealthyThresholdCount` consecutive failures (default 2) and put back after `HealthyThresholdCount` successes (default 5).** The load balancer closes idle connections after 60 seconds by default, so targets must keep connections open longer than that.

## Health check settings (target group)

| Setting | Range | Default |
|---|---|---|
| `HealthCheckProtocol` | HTTP, HTTPS (GET) | HTTP |
| `HealthCheckPort` | port or `traffic-port` | the traffic port |
| `HealthCheckPath` | URI; gRPC `/package.service/method` | `/`; gRPC `/AWS.ALB/healthcheck` |
| `HealthCheckTimeoutSeconds` | 2–120 | 5 (instance/ip), 30 (lambda) |
| `HealthCheckIntervalSeconds` | 5–300 | 30 (instance/ip), 35 (lambda) |
| `HealthyThresholdCount` | 2–10 | 5 |
| `UnhealthyThresholdCount` | 2–10 | 2 |
| `Matcher` | HTTP 200–499 (lists or ranges); gRPC 0–99 | `200`; gRPC `12` |

```
aws elbv2 modify-target-group --target-group-arn <tg> \
  --health-check-path /healthz --matcher HttpCode=200-399 \
  --health-check-interval-seconds 15 --healthy-threshold-count 2
```

What the request looks like:

- `Host:` is the target's **private IP**, plus `:port` when the port isn't the default. Apps that route by host name, or redirect unknown hosts, fail the check: give the health path a default virtual host.
- `User-Agent: ELB-HealthChecker/2.0`.
- WebSockets aren't supported for health checks.

Time to become healthy is roughly `HealthyThresholdCount × HealthCheckIntervalSeconds` once it starts passing (with defaults: 5 × 30 s). Container platforms with short start-up grace periods can kill tasks before then (UNVERIFIED arithmetic; the page states the thresholds, not the total).

### States

`initial` → `healthy` / `unhealthy`. A target is `unused` when it is not registered, not used by a listener rule, in an AZ the load balancer doesn't have enabled, or stopped. Deregistering targets are `draining`, and `unavailable` means checks are disabled. Reason codes are in `reference/elb/errors.md`.

**Fail-open:** if every target in the group is unhealthy, the load balancer routes to all of them. Deregistering a target lowers `HealthyHostCount` without raising `UnhealthyHostCount`.

Health check logs can be written to S3 for detailed diagnosis.

## Load balancer attributes

| Attribute key | Range | Default | Why it matters |
|---|---|---|---|
| `idle_timeout.timeout_seconds` | 1–4000 | 60 | Connections idle this long are closed. Long uploads need ≥1 byte per interval. Set the **target's keep-alive longer than this**, or you get intermittent 502s. HTTP/2 PING frames don't reset it |
| `client_keep_alive.seconds` | 60–604800 | 3600 | Maximum life of a client connection. Then the load balancer sends `Connection: close` (HTTP/1.x) or GOAWAY (HTTP/2). Lower it for faster recovery after zonal shifts |
| `routing.http.desync_mitigation_mode` | monitor, defensive, strictest | defensive | How non-RFC 7230 requests are treated. *Severe* requests get 400 in defensive mode; strictest also blocks *Acceptable* and *Ambiguous* |
| `routing.http.preserve_host_header.enabled` | true/false | false | When off, a non-default listener port is appended to `Host`, and a port on 80/443 is stripped |
| `deletion_protection.enabled` | true/false | false | Must be turned off before deleting |

```
aws elbv2 modify-load-balancer-attributes --load-balancer-arn <lb> \
  --attributes Key=idle_timeout.timeout_seconds,Value=120 Key=deletion_protection.enabled,Value=true
```

## Other fixed timeouts

- Connection to a target: 10 s, then 504.
- TLS handshake to a target: 10 s, then 504.
- HTTP/2 connections are closed after 10,000 requests.
- Header limits: 16 KB per request line, 16 KB per header, 64 KB in total; 32 KB of response headers from a target.
- Lambda targets: 1 MB request and response bodies.


---
<!-- 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 -->
