---
cuppy_hub: aws
cuppy_path: reference/vpc/flow-logs.md
cuppy_section: docs
cuppy_doc: XC9F-XK6H
cuppy_doc_uuid: e767feb2-a2fc-4f04-9390-5c3b6577b6f8
cuppy_permalink: https://cuppy.io/aws/d/XC9F-XK6H
cuppy_version: 4
cuppy_updated: 2026-10-23T16:16:52.575Z
cuppy_canonical: https://cuppy.io/aws/docs/reference/vpc/flow-logs
cuppy_mcp: https://cuppy.io/mcp
cuppy_body_sha256: 88467f69ebb6110c6e257cc526e7beaedd559089ae3413ea57912c11dc3bb0e3
# cuppy_body_sha256 is over the document body ALONE, excluding both generated blocks.
---


# Reading VPC Flow Logs

**A flow log record says that traffic between two addresses and ports was ACCEPTed or REJECTed at a network interface during a capture window.** A `REJECT` means a security group or network ACL dropped it, or packets arrived after the connection had closed. Here is how to read one, and what flow logs can't tell you.

## Default format (version 2), in order

```
version account-id interface-id srcaddr dstaddr srcport dstport protocol packets bytes start end action log-status
```

| Field | Meaning |
|---|---|
| `interface-id` | The network interface the flow was recorded on (`-` for a regional NAT gateway's flows) |
| `srcaddr` / `dstaddr` | For incoming traffic, the source; for outgoing traffic, the interface's **private** IPv4 or IPv6 address. Not the original address when NAT is in the path (use `pkt-srcaddr`/`pkt-dstaddr`) |
| `protocol` | IANA number: 6 TCP, 17 UDP, 1 ICMP |
| `start` / `end` | Unix seconds of the first and last packet in the window (±60 s) |
| `action` | `ACCEPT` or `REJECT` |
| `log-status` | `OK`; `NODATA` (no traffic in the window); `SKIPDATA` (records skipped for internal capacity reasons) |

A field that doesn't apply shows `-`. Fields like `account-id` can show `unknown` for interfaces AWS services create.

## Timing

- Aggregation window: up to 10 minutes by default, or 1 minute if chosen. Interfaces on Nitro instances are always ≤1 minute.
- Delivery: typically about 5 minutes to CloudWatch Logs and about 10 minutes to S3. Best effort, so a fresh test may not appear yet.

## Reading a failed connection

To find the REJECT lines in a flow log's log group, use the Logs Insights queries in `reference/cloudwatch/logs-insights-queries.md`.

| You see | It means |
|---|---|
| Client → server `REJECT` on the server's interface | The server's security group or the subnet's NACL dropped the request |
| Request `ACCEPT`, the reply `REJECT` | Almost always a **NACL** blocking the return on ephemeral ports (security groups are stateful) |
| Nothing at the destination interface | The traffic never arrived: **routes**, gateways, or VPC Block Public Access upstream. Check the source interface's records |
| `ACCEPT` both ways, but the app still fails | The network is fine; look at the application, TLS or DNS |
| Late `REJECT`s on an old connection | Packets after the connection closed, for example after an NLB or NAT idle timeout |

## Custom fields worth adding

Specify a custom format to include them (at least one field):

| Field (version) | Answers |
|---|---|
| `pkt-srcaddr`, `pkt-dstaddr` (v3) | The original addresses behind a NAT gateway, or an EKS pod behind its node |
| `tcp-flags` (v3) | SYN 2, SYN-ACK 18, FIN 1, RST 4 (flags are OR-ed within a window). SYNs with no SYN-ACK mean the server never answered |
| `vpc-id`, `subnet-id`, `instance-id` (v3) | Where the interface lives |
| `flow-direction` (v5) | `ingress` or `egress` at this interface |
| `traffic-path` (v5) | Egress via 1 same VPC, 2 IGW or gateway endpoint, 3 VGW, 4 intra-Region peering, 5 inter-Region peering, 6 Local or Wavelength Zone, 7 gateway endpoint, 8 IGW |
| `pkt-src-aws-service`, `pkt-dst-aws-service` (v5) | The AWS service range of the address (e.g. `S3`, `CLOUDFRONT_ORIGIN_FACING`, `ROUTE53_RESOLVER`) |
| `ecs-cluster-name`, `ecs-service-name`, `ecs-task-arn` (v7) | Which ECS task produced the flow (the flow log's role needs `ecs:List*` permissions) |
| `reject-reason` (v8) | `BPA` (VPC Block Public Access) or `EC` (rejected by VPC Encryption Controls); `-` for other rejects such as SG or NACL |
| `resource-id` (v9) | The regional NAT gateway |
| `encryption-status` (v10) | 0 not encrypted, 1 Nitro-encrypted, 2 application-encrypted (inferred from port 443 for endpoints), 3 both |
| `interface-type`, `next-hop-*` (v11) | What the interface belongs to (`nat_gateway`, `network_load_balancer`, `vpc_endpoint`…) and the next hop |

## Limits of what it shows

- Packets aren't captured, only per-flow summaries.
- Traffic that security groups and NACLs can't see, such as DNS to the Route 53 Resolver and IMDS, isn't a firewall question (`reference/vpc/security-groups-and-nacls.md`).
- Flow logs record what happened. To learn *why* a path is blocked before sending traffic, use Reachability Analyzer (`guides/vpc/diagnose-connection-timeout.md`).
- Turning on flow logs is `aws ec2 create-flow-logs` with a resource (VPC, subnet or network interface), traffic type and destination (CloudWatch Logs with a delivery role, or S3) (UNVERIFIED parameter names in the collected sources).


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