Confirming from the Logs That a CloudFront VPC Origin Outage (2026-07-16) Caused Timeout Waits of About 30 Seconds
This page has been translated by machine translation. View original
Introduction
On 2026-07-16 (JST 16:45–20:18), a failure occurred in CloudFront VPC origins. The final report on the AWS Service Health Dashboard explains the root cause as follows.
We identified the root cause of the issue as an internal constraint on the fleet that manages connections to private VPC origins. When this constraint was reached, the system responsible for distributing routing configuration to our network processors failed to load the updated configuration data correctly, affecting routing of VPC Origin connections.
The cause was that the fleet managing private connections to VPC origins reached an internal constraint, and distribution of routing configuration to the network processors failed.

The temporary workaround on the day of the failure (building a bypass configuration using Inter-Region VPC peering) is covered in the following article.
In this article, I analyzed the impact of the failure using the CloudFront access logs and ALB access logs located before and after the VPC origin. The target system is configured with a CloudFront Origin Failover Group with the following two paths.
- primary: CloudFront → VPC Origin → Internal ALB (3 AZs) → ECS
- secondary: CloudFront → Cloudflare Workers (for degraded operation)
Verification
Verification environment
| Item | Value |
|---|---|
| Target | dev.classmethod.jp (DevelopersIO) |
| CloudFront Distribution | E2XXXXXXXXXXXX |
| VPC Origin | vo_XXXXXXXXXXXXXXXXXXXXXXXX → Internal ALB (3 AZs) |
| Failover Group | primary = VPC Origin, secondary = Cloudflare Workers (for degraded operation) |
| ALB nodes | 3 AZs (AZ-a, AZ-c, AZ-d) |
| ConnectionTimeout (at the time of failure) | 10 seconds |
| ConnectionAttempts (at the time of failure) | 3 |
| OriginReadTimeout (at the time of failure) | 30 seconds |
Onset of the failure as seen in the ALB logs
Before the failure (07:30–07:53), the ALB was processing normally in all AZs, HTTP responses were almost all 200/308/404 (only 2 were 500), and the average response time was 0.097–0.102 seconds.
The following is the number of requests per second from 07:53:30 to 07:53:55 (UTC).
| Time (UTC) | AZ-a | AZ-c | AZ-d | Total |
|---|---|---|---|---|
| 07:53:30 | 5 | 2 | 4 | 11 |
| 07:53:31 | 0 | 4 | 1 | 5 |
| 07:53:32 | 2 | 2 | 2 | 6 |
| 07:53:33 | 2 | 1 | 2 | 5 |
| 07:53:34 | 1 | 1 | 1 | 3 |
| 07:53:35 | 1 | 2 | 6 | 9 |
| 07:53:36 | 5 | 3 | 0 | 8 |
| 07:53:37 | 2 | 4 | 2 | 8 |
| 07:53:38 | 3 | 0 | 2 | 5 |
| 07:53:39 | 0 | 2 | 1 | 3 |
| 07:53:40 | 3 | 2 | 4 | 9 |
| 07:53:41 | 2 | 3 | 2 | 7 |
| 07:53:42 | 3 | 1 | 0 | 4 |
| 07:53:43 | 0 | 2 | 0 | 2 |
| 07:53:44 | 3 | 2 | 4 | 9 |
| 07:53:45 | 1 | 1 | 3 | 5 |
| 07:53:46 | 1 | 0 | 1 | 2 |
| 07:53:47 | 0 | 1 | 0 | 1 |
| 07:53:48 | 0 | 0 | 0 | 0 |
| 07:53:49 | 0 | 0 | 1 | 1 |
| 07:53:50 | 1 | 0 | 0 | 1 |
| 07:53:51 | 0 | 0 | 0 | 0 |
| 07:53:52 | 0 | 0 | 0 | 0 |
| 07:53:53 | 0 | 0 | 0 | 0 |
| 07:53:54 | 0 | 0 | 0 | 0 |
| 07:53:55 | 0 | 0 | 0 | 0 |
The last request in each AZ was AZ-c: 07:53:47, AZ-d: 07:53:49, and AZ-a: 07:53:50, so they stopped one after another within about 3 seconds. This shows that it was not a failure of a specific AZ, but that requests stopped reaching all AZs at once.
There were no signs of failure on the ALB/ECS side, so we can conclude that the failure occurred at a stage before reaching the ALB. This observation is consistent with the impact on VPC origin connections announced by AWS.
The reality of the timeouts as seen in the CloudFront logs
The following is a time series of the CloudFront access logs before and after the failure (29,251 origin_request entries), aggregated per minute. The ok column shows the number of requests with sc_status 2xx/3xx, and the err column shows the number of requests with sc_status 0 or 5xx. 4xx is not included in either, so some rows have ok+err not equal to total.
| Time (UTC) | total | ok | err | ok rate | p95_t (sec) | Notes |
|---|---|---|---|---|---|---|
| 07:50 | 367 | 367 | 0 | 100.0% | 1.315 | Normal |
| 07:51 | 404 | 404 | 0 | 100.0% | 1.397 | Normal |
| 07:52 | 385 | 381 | 0 | 99.0% | 1.452 | Normal |
| 07:53 | 310 | 271 | 39 | 87.4% | 4.765 | First error occurred (07:53:45) |
| 07:54 | 260 | 60 | 200 | 23.1% | 30.624 | Failure in full swing |
| 07:55 | 307 | 57 | 250 | 18.6% | 30.382 | Failure continuing |
| 07:56 | 332 | 87 | 245 | 26.2% | 30.313 | Failure continuing |
| 07:57 | 376 | 98 | 278 | 26.1% | 30.363 | Failure continuing |
| 07:58 | 339 | 78 | 261 | 23.0% | 30.328 | Failure continuing |
The first error (sc_status=0) occurred at 07:53:45, and from 07:54 onward the p95 response time is stuck at about 30.3 seconds. This value is consistent with about 30 seconds, which corresponds to the configured timeouts (OriginReadTimeout 30 seconds, or ConnectionTimeout 10 seconds × 3 attempts), meaning communication with the VPC origin stalled at some stage and reached the timeout (which one was dominant is discussed later).
Full table (07:30–08:29 UTC)
| Time (UTC) | total | ok | err | ok rate | avg_t | p95_t |
|---|---|---|---|---|---|---|
| 07:30 | 355 | 355 | 0 | 100.0% | 0.493 | 1.285 |
| 07:31 | 409 | 405 | 0 | 99.0% | 0.516 | 1.188 |
| 07:32 | 314 | 314 | 0 | 100.0% | 0.471 | 1.243 |
| 07:33 | 328 | 328 | 0 | 100.0% | 0.374 | 1.088 |
| 07:34 | 339 | 339 | 0 | 100.0% | 0.454 | 1.201 |
| 07:35 | 340 | 340 | 0 | 100.0% | 0.474 | 1.207 |
| 07:36 | 489 | 489 | 0 | 100.0% | 0.535 | 1.264 |
| 07:37 | 384 | 384 | 0 | 100.0% | 0.535 | 1.231 |
| 07:38 | 339 | 339 | 0 | 100.0% | 0.421 | 1.165 |
| 07:39 | 368 | 368 | 0 | 100.0% | 0.430 | 1.182 |
| 07:40 | 344 | 340 | 0 | 98.8% | 0.438 | 1.128 |
| 07:41 | 375 | 375 | 0 | 100.0% | 0.460 | 1.309 |
| 07:42 | 347 | 347 | 0 | 100.0% | 1.132 | 1.345 |
| 07:43 | 382 | 378 | 0 | 99.0% | 0.438 | 1.269 |
| 07:44 | 290 | 290 | 0 | 100.0% | 0.446 | 1.242 |
| 07:45 | 380 | 379 | 1 | 99.7% | 0.475 | 1.187 |
| 07:46 | 464 | 464 | 0 | 100.0% | 0.503 | 1.089 |
| 07:47 | 305 | 305 | 0 | 100.0% | 0.461 | 1.165 |
| 07:48 | 310 | 309 | 1 | 99.7% | 0.467 | 1.189 |
| 07:49 | 322 | 322 | 0 | 100.0% | 0.486 | 1.420 |
| 07:50 | 367 | 367 | 0 | 100.0% | 0.469 | 1.315 |
| 07:51 | 404 | 404 | 0 | 100.0% | 0.513 | 1.397 |
| 07:52 | 385 | 381 | 0 | 99.0% | 0.509 | 1.452 |
| 07:53 | 310 | 271 | 39 | 87.4% | 1.006 | 4.765 |
| 07:54 | 260 | 60 | 200 | 23.1% | 11.771 | 30.624 |
| 07:55 | 307 | 57 | 250 | 18.6% | 11.022 | 30.382 |
| 07:56 | 332 | 87 | 245 | 26.2% | 14.046 | 30.313 |
| 07:57 | 376 | 98 | 278 | 26.1% | 14.017 | 30.363 |
| 07:58 | 339 | 78 | 261 | 23.0% | 12.366 | 30.328 |
| 07:59 | 368 | 69 | 299 | 18.8% | 10.746 | 30.303 |
| 08:00 | 377 | 102 | 275 | 27.1% | 13.573 | 30.513 |
| 08:01 | 531 | 82 | 449 | 15.4% | 11.630 | 30.316 |
| 08:02 | 553 | 76 | 477 | 13.7% | 11.451 | 30.305 |
| 08:03 | 453 | 90 | 359 | 19.9% | 12.650 | 30.317 |
| 08:04 | 526 | 83 | 443 | 15.8% | 11.058 | 30.299 |
| 08:05 | 651 | 105 | 546 | 16.1% | 11.660 | 30.299 |
| 08:06 | 640 | 116 | 524 | 18.1% | 12.257 | 30.297 |
| 08:07 | 739 | 94 | 645 | 12.7% | 10.724 | 30.288 |
| 08:08 | 535 | 97 | 438 | 18.1% | 11.361 | 30.313 |
| 08:09 | 608 | 98 | 510 | 16.1% | 11.294 | 30.285 |
| 08:10 | 793 | 99 | 694 | 12.5% | 11.047 | 30.287 |
| 08:11 | 785 | 113 | 672 | 14.4% | 11.355 | 30.288 |
| 08:12 | 804 | 107 | 697 | 13.3% | 10.195 | 30.294 |
| 08:13 | 663 | 105 | 558 | 15.8% | 10.845 | 30.294 |
| 08:14 | 405 | 79 | 326 | 19.5% | 11.618 | 30.301 |
| 08:15 | 657 | 89 | 568 | 13.5% | 10.381 | 30.285 |
| 08:16 | 670 | 111 | 559 | 16.6% | 11.818 | 30.299 |
| 08:17 | 784 | 96 | 688 | 12.2% | 10.840 | 30.282 |
| 08:18 | 752 | 97 | 655 | 12.9% | 10.990 | 30.262 |
| 08:19 | 823 | 103 | 716 | 12.5% | 11.632 | 30.278 |
| 08:20 | 754 | 82 | 672 | 10.9% | 10.117 | 30.214 |
| 08:21 | 719 | 96 | 619 | 13.4% | 10.930 | 30.300 |
| 08:22 | 700 | 100 | 600 | 14.3% | 10.379 | 30.300 |
| 08:23 | 430 | 81 | 349 | 18.8% | 11.878 | 30.312 |
| 08:24 | 450 | 79 | 371 | 17.6% | 11.145 | 30.313 |
| 08:25 | 651 | 102 | 549 | 15.7% | 11.279 | 30.307 |
| 08:26 | 678 | 104 | 570 | 15.3% | 11.179 | 30.297 |
| 08:27 | 545 | 85 | 460 | 15.6% | 10.498 | 30.298 |
| 08:28 | 461 | 91 | 370 | 19.7% | 12.365 | 30.362 |
| 08:29 | 482 | 103 | 379 | 21.4% | 12.060 | 30.361 |
The breakdown of errors is as follows.
| Error type | Count | Share | Meaning |
|---|---|---|---|
| ClientCommError | 15,672 | 89.3% | A category recorded as a communication interruption between CloudFront and the viewer |
| ClientHungUpRequest | 1,872 | 10.7% | The viewer closed the connection before the response completed |
ClientHungUpRequest (1,872 cases) are cases where the viewer closed the connection before the response completed. Most of the rest are ClientCommError (a category recorded as a communication interruption between CloudFront and the viewer), and given the correlation with the failure period, they are presumed to have occurred against the background of origin timeouts.
Errors occurred simultaneously across a wide range of CloudFront edge locations in multiple regions, and no bias toward a specific PoP was observed.
By path, /articles/* accounted for 72.4% of the errors, a distribution that reflects the site's traffic composition.
Effect and limits of origin failover
Even during the failure, there were 60–116 successful responses per minute, and the ok rate stayed at 10–27% throughout the failure (07:54–08:29). Since 2xx responses were being returned while the VPC origin could not respond, it is presumed that the Cloudflare Workers configured as the secondary origin were returning the responses.
On Cloudflare Workers (devio-front-failback), Invocations, which are normally almost 0, increased to a maximum of 2.1k/minute.

Invocations of Cloudflare Workers (devio-front-failback)
I also confirmed pages on which the banner for degraded operation was actually displayed.

The banner displayed during degraded operation
However, there was a problem in the process until failover was triggered. When CloudFront reaches a timeout while establishing a connection to the primary origin or retrieving a response, it tries the secondary according to the configured failover criteria. In these logs, a wait of about 30 seconds was observed, and the structure was such that users were served the degraded page only after that wait.
When the origin failover group was configured, I had assumed the case where the primary origin returns an HTTP error (such as 5XX) set as a failover trigger. However, what actually occurred was the phenomenon of "no response at all from the origin," and the secondary was tried only after waiting for the timeout (about 30 seconds) to expire.
Policy for the interim measures
The timeout settings to be reviewed are as follows.
| Setting | Current value |
|---|---|
| OriginReadTimeout | 30 seconds |
| ConnectionTimeout | 10 seconds |
| ConnectionAttempts | 3 |
The cause of this failure is said to be the failure to distribute the routing configuration of the VPC origin. Since the p95 matches the OriginReadTimeout of 30 seconds, it is possible that the TCP connection was established but no response was returned, but the logs in this article do not let us directly determine whether the connection was established. Shortening OriginReadTimeout is the primary improvement measure, but because it is necessary to balance it against the SSR response time during normal operation, the appropriate value will be decided after verification. Shortening ConnectionTimeout/ConnectionAttempts is planned to be carried out as well, as preparation for cases where establishing the connection itself fails.
Improvements identified in this analysis
To remove the constraint mentioned above, I added fields to the CloudFront access logs. They are three: origin-fbl (origin first byte latency), origin-lbl (origin last byte latency), and timestamp(ms) (timestamp with millisecond precision).
Summary
This log analysis confirmed that during the VPC origin failure, CloudFront was in a state where it waited about 30 seconds for a timeout. Although origin failover was functioning, it had to wait for the primary origin's timeout determination, so the wait time until the degraded response became an issue.
In addition, for the timeout type and per-request behavior that could not be identified this time, by using the added log fields, we expect to be able to capture origin-side latency and time correlations in more detail going forward.
Going forward, after verifying the behavior in a reproduction environment, I plan to optimize CloudFront's timeout settings and origin failover settings and apply them as measures to prevent recurrence.
