You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CloudFront /api/*行为偶发路由到S3返回NoSuchKey报错

问题背景

使用CloudFront分发时配置了两个缓存行为:

  • 默认行为对接S3存储桶,提供静态内容
  • 路径模式为/api/*的附加行为对接独立HTTP源站,作为后端API访问入口
    对应的CDK部署代码如下:
const distribution = new Distribution(this, `${this.constructPrefix}-cloudfront-${this.constructSuffix}`, {
            defaultBehavior: {
                origin: new S3Origin(bucket, {
                    originAccessIdentity: oai,
                }),
                functionAssociations: [
                    {
                        function: cloudfrontFunctionRewritePath,
                        eventType: FunctionEventType.VIEWER_REQUEST,
                    },
                ],
                viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
                cachePolicy: frontCachePolicy,
            },
            additionalBehaviors: {
                "/api/*": {
                    origin: new HttpOrigin(`${buildConfig.ApiURL}`, {
                        httpsPort: 443,
                        protocolPolicy: OriginProtocolPolicy.HTTPS_ONLY,
                        customHeaders: {
                            "x-cloudfront-secret": `${cloudfrontSecret.secretValueFromJson("password")}`,
                        },
                    }),
                    cachePolicy: apiCachePolicy,
                    viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
                    allowedMethods: AllowedMethods.ALLOW_ALL,
                    edgeLambdas: edgeLambdaAssociations,
                    
                },
            },
            logBucket: bucketLog,
            logFilePrefix: "cloudfront/",
            enabled: true,
            defaultRootObject: "index.html",
            domainNames: [domainName],
            certificate: secureCertificate,
            errorResponses: [
                {
                    httpStatus: 404,
                    responseHttpStatus: 200,
                    responsePagePath: "/index.html",
                    ttl: Duration.seconds(86400),
                },
            ],
            ...(buildConfig.AWSWebAclArn !== "NONE" ? { webAclId: buildConfig.AWSWebAclArn } : {}),
        });
故障现象

API端点/api/endpoint随机返回HTTP 404,报错内容为no such key the specified key does not exist,其余API端点均正常。异常响应携带Server: AmazonS3响应头,判断为CloudFront偶发未将该路径请求匹配到/api/*对应的HTTP源站,错误命中对接S3的默认行为。故障无稳定复现规律,需要明确排查方向。

排查思路(按故障概率从高到低排序)
  • 优先排查默认行为绑定的Viewer Request级CloudFront Function(cloudfrontFunctionRewritePath):这是最高概率的根因。Viewer Request层级的关联函数执行优先级高于缓存行为匹配,所有请求无论对应哪个路径,都会先经过该函数处理。只要函数内存在分支逻辑bug,比如对不带尾斜杠的路径、携带特殊query参数、特定请求方法的场景处理遗漏,偶发把/api/endpoint的URI改写为非/api/开头的形式,请求就会直接跳过/api/*规则匹配,落到S3默认源。直接在CloudFront控制台给该函数加测试用例,模拟/api/endpoint的所有请求变体(不同请求方法、带/不带尾斜杠、带不同query参数、带常规业务header),验证函数输出的URI是否始终保持/api/前缀即可。
  • 排查API缓存策略的缓存污染问题:检查apiCachePolicy的缓存键配置,如果策略未正确隔离不同路径的缓存,之前某次错误配置导致S3返回的404响应被边缘节点缓存,后续命中该缓存的请求就会直接返回S3的错误响应。可以先手动发起针对/api/endpoint的缓存失效操作,观察故障是否消失;同时确认缓存策略是否将不必要的header、query参数排除出缓存键,避免跨路径的缓存串扰。
  • 检查Edge Lambda运行异常:/api/*行为绑定的edgeLambdaAssociations如果存在Origin Request级别的函数偶发超时、执行报错,不会直接把错误返回给客户端,而是会自动跳过当前行为的源站配置,回退到默认行为的S3源。直接去CloudWatch筛选故障时间点、对应边缘节点的Lambda@Edge日志,查看是否有执行报错、超时、权限异常的记录即可。
  • 核对路径匹配规则的边界:CloudFront路径模式大小写敏感,如果客户端偶发发起的请求路径为/API/endpoint、/api/Endpoint这类大小写不匹配的形式,就不会命中/api/*规则,直接落到S3。去CloudFront访问日志里筛选返回S3 404的请求,查看cs-uri-stem字段记录的实际请求路径,确认是否完全符合/api/*的前缀要求即可。
  • 确认分发配置的传播状态:如果近期修改过/api/*的行为配置,CloudFront的配置更新是逐边缘节点传播的,传播窗口期(通常5-15分钟,极端情况可能到1小时)内会出现部分节点加载了新配置、部分节点仍使用旧配置的情况,如果旧配置未正确设置/api/*路径,就会出现偶发落S3的问题。可以通过不同地域的探测点发起请求,确认故障是否和特定地域/边缘节点强相关,如果是等待配置全量传播完成即可。

补充提示:当前配置的404错误响应规则是把所有404改写为返回/index.html,如果故障时返回的是S3原生的XML格式404报错而不是index.html内容,基本可以排除配置传播问题,优先查函数改写和缓存污染两类问题。

内容的提问来源于stack exchange,提问作者Quentin Barbault

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 12:31:10