

# HTTP 502 状态代码（无效网关）
<a name="http-502-bad-gateway"></a>

当 CloudFront 因无法连接至原始服务器而无法提供请求的对象时，CloudFront 返回 HTTP 502 状态代码（无效网关）。

如果您使用的是 Lambda@Edge，则问题可能是 Lambda 验证错误。如果您收到了 HTTP 502 错误以及 `NonS3OriginDnsError` 错误代码，则可能是 DNS 配置问题，导致 CloudFront 无法连接到源。

**Topics**
+ [CloudFront 与自定义源服务器之间的 SSL/TLS 协商失败](#ssl-negotitation-failure)
+ [源没有使用支持的密码/协议进行响应](#origin-not-responding-with-supported-ciphers-protocols)
+ [源中的 SSL/TLS 证书已过期、无效、为自签名或证书链的顺序错误](#ssl-certificate-expired)
+ [源在“源设置”中的指定端口上没有响应](#origin-not-responding-on-specified-ports)
+ [Lambda 验证错误](#http-502-lambda-validation-error)
+ [CloudFront 函数验证错误](#http-502-cloudfront-function-validation-error)
+ [DNS 错误（`NonS3OriginDnsError`）](#http-502-dns-error)
+ [Application Load Balancer 源 502 错误](#cloudfront-alb-502-error)
+ [API Gateway 源 502 错误](#cloudfront-api-gateway-502-error)

## CloudFront 与自定义源服务器之间的 SSL/TLS 协商失败
<a name="ssl-negotitation-failure"></a>

如果您使用的自定义源要求在 CloudFront 与源之间使用 HTTPS，则不匹配的域名可能会导致错误。源上的 SSL/TLS 证书*必须* 包含与您为 CloudFront 分配指定的**源域**或源请求的 `Host` 标头相匹配的域名。

如果域名不匹配，SSL/TLS 握手将失败，CloudFront 将返回 HTTP 状态代码 502（无效网关）并将 `X-Cache` 标头设置为 `Error from cloudfront`。

要确定证书中的域名是否与分配或 `Host` 标头中的**源域**匹配，可以使用在线 SSL 检查程序或 OpenSSL。如果域名不匹配，则有两个选项：
+ 获取包含相应域名的新 SSL/TLS 证书。

  如果您使用 AWS Certificate Manager（ACM），请参阅《AWS Certificate Manager 用户指南》**中的[请求证书](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html)来请求新证书。
+ 更改分配配置，以使 CloudFront 不再尝试使用 SSL 来连接源。

### 在线 SSL 检查程序
<a name="troubleshooting-ssl-negotiation-failure-online-ssl-checker"></a>

要查找 SSL 测试工具，请在 Internet 上搜索“在线 ssl 检查程序。” 通常情况下，您指定域名，该工具将返回有关 SSL/TLS 证书的各种信息。确认在证书的**公用名**或**使用者备用名称**字段中包含您的域名。

### OpenSSL
<a name="troubleshooting-ssl-negotiation-failure-openssl"></a>

要帮助纠正来自 CloudFront 的 HTTP 502 错误，您可以使用 OpenSSL 尝试与源服务器建立 SSL/TLS 连接。如果 OpenSSL 无法建立连接，则可能表明源服务器的 SSL/TLS 配置出错。如果 OpenSSL 能够建立连接，它将返回有关源服务器证书的信息，包括证书的公用名称（`Subject CN` 字段）和使用者备用名称（`Subject Alternative Name` 字段）。

使用以下 OpenSSL 命令测试与源服务器的连接（将*源域*替换为源服务器的域名，如 example.com）：

`openssl s_client -connect origin domain name:443`

如果满足以下条件：
+ 您的源服务器支持具有多个 SSL/TLS 证书的多个域名
+ 您的分配已配置为将 `Host` 标头转发到源

然后，将 `-servername` 选项添加到 OpenSSL 命令中，如以下示例所示（将 *CNAME* 替换为分配中配置的 CNAME）：

`openssl s_client -connect origin domain name:443 -servername CNAME`

## 源没有使用支持的密码/协议进行响应
<a name="origin-not-responding-with-supported-ciphers-protocols"></a>

CloudFront 使用密码和协议连接到源服务器。有关 CloudFront 支持的密码和协议列表，请参阅 [CloudFront 与源之间受支持的协议和密码](secure-connections-supported-ciphers-cloudfront-to-origin.md)。如果您的源在 SSL/TLS 交换中不用这些密码或协议之一进行响应，则 CloudFront 无法连接。可以使用 [SSL Labs](https://www.ssllabs.com/ssltest) 之类的在线工具验证源是否支持密码和协议。在 **Hostname** 字段中键入源的域名，然后选择 **Submit**。查看测试中的 **Common names** 和 **Alternative names** 字段，以确定它们是否与源的域名匹配。测试完成后，在测试结果中查找 **Protocols** 和 **Cipher Suites** 部分，以确定源支持的密码和协议。将它们与 [CloudFront 与源之间受支持的协议和密码](secure-connections-supported-ciphers-cloudfront-to-origin.md) 的列表比较。

## 源中的 SSL/TLS 证书已过期、无效、为自签名或证书链的顺序错误
<a name="ssl-certificate-expired"></a>

如果源服务器返回以下内容，CloudFront 将中断 TCP 连接、返回 HTTP 状态代码 502（无效网关），并将 `X-Cache` 标头设置为 `Error from cloudfront`：
+ 过期的证书
+ 无效的证书
+ 自签名证书
+ 证书链的顺序错误

**注意**  
如果不存在完整的证书链（包括中间证书），CloudFront 将中断 TCP 连接。

有关在自定义源服务器上安装 SSL/TLS 证书的信息，请参阅 [要求在 CloudFront 与您的自定义源之间使用 HTTPS 进行通信](using-https-cloudfront-to-custom-origin.md)。

## 源在“源设置”中的指定端口上没有响应
<a name="origin-not-responding-on-specified-ports"></a>

在 CloudFront 分配中创建源时，您可以为 HTTP 和 HTTPS 流量设置 CloudFront 用于连接到源的端口。默认情况下，这些端口为 TCP 80/443。您可以选择修改这些端口。如果源出于任何原因拒绝这些端口上的流量，或者后端服务器在这些端口上无响应，CloudFront 将无法连接。

要解决这些问题，请检查您的基础设施中运行的任何防火墙并确认它们未阻止支持的 IP 范围。有关更多信息，请参阅《Amazon VPC 用户指南》**中的 [AWS IP 地址范围](https://docs.aws.amazon.com/vpc/latest/userguide/aws-ip-ranges.html)。此外，还要验证您的 Web 服务器是否正在源中运行。

## Lambda 验证错误
<a name="http-502-lambda-validation-error"></a>

如果使用的是 Lambda@Edge，则 HTTP 502 状态代码可能指示未正确设置 Lambda 函数响应格式或包含无效的内容。有关排查 Lambda@Edge 错误的更多信息，请参阅[测试和调试 Lambda@Edge 函数](lambda-edge-testing-debugging.md)。

## CloudFront 函数验证错误
<a name="http-502-cloudfront-function-validation-error"></a>

如果使用的是 CloudFront 函数，HTTP 502 状态代码可能指示 CloudFront 函数正在尝试添加、删除或更改只读标头。此错误不会在测试期间出现，但会在您部署函数并运行请求后出现。要解决此错误，请检查并更新 CloudFront 函数。有关更多信息，请参阅 [更新函数](update-function.md)。

## DNS 错误（`NonS3OriginDnsError`）
<a name="http-502-dns-error"></a>

错误代码为 `NonS3OriginDnsError` 的 HTTP 502 错误表示存在 DNS 配置问题，导致 CloudFront 无法连接到源。如果您从 CloudFront 收到此错误，请确保源的 DNS 配置正确且有效。

当 CloudFront 收到针对已过期或不在缓存中的对象的请求时，它会向源发出请求，以获取该对象。为了成功向源发出请求，CloudFront 会对源域执行 DNS 解析。如果您的域的 DNS 服务出现问题时，CloudFront 将无法解析域名以获取 IP 地址，从而导致 HTTP 502 错误 (`NonS3OriginDnsError`)。要修复此问题，请联系您的 DNS 提供商，或者，如果您使用的是 Amazon Route 53，请参阅[为什么我无法访问使用 Route 53 DNS 服务的网站？](https://aws.amazon.com/premiumsupport/knowledge-center/route-53-dns-website-unreachable/)

要进一步解决该问题，请确保源的根域或顶级域（如 `example.com`）的[权威名称服务器](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/route-53-concepts.html#route-53-concepts-authoritative-name-server)运行正常。您可以通过 [dig](https://en.wikipedia.org/wiki/Dig_(command)) 或 [nslookup](https://en.wikipedia.org/wiki/Nslookup)等工具，使用以下命令查找顶级源的名称服务器：

```
dig OriginAPEXDomainName NS +short
```

```
nslookup -query=NS OriginAPEXDomainName
```

如果您有名称服务器的名称，请使用以下命令针对这些名称查询源的域名，以确保每个查询都会得到响应：

```
dig OriginDomainName @NameServer
```

```
nslookup OriginDomainName NameServer
```

**重要**  
确保使用连接到公共互联网的计算机执行此 DNS 故障排除。CloudFront 使用互联网上的公有 DNS 解析源域，因此在类似环境中进行故障排除非常重要。

如果您的源是一个子域，其 DNS 权限被委托给与根域不同的域名服务器，请确保为该子域正确配置域名服务器 (`NS`) 和授权起始点 (`SOA`) 记录。您可以使用与上述示例类似的命令来检查这些记录。

有关 DNS 的更多信息，请参阅 Amazon Route 53 文档中的[域名系统 (DNS) 概念](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/route-53-concepts.html#route-53-concepts-domain-name-system-dns)。

## Application Load Balancer 源 502 错误
<a name="cloudfront-alb-502-error"></a>

如果您使用应用程序负载均衡器作为源并收到 502 错误，请参阅[如何排查应用程序负载均衡器 HTTP 502 错误？](https://repost.aws/knowledge-center/elb-alb-troubleshoot-502-errors)。

## API Gateway 源 502 错误
<a name="cloudfront-api-gateway-502-error"></a>

如果您使用 API Gateway 并收到 502 错误，请参阅[如何使用 Lambda 代理集成解决来自 API Gateway REST API 的 HTTP 502 错误？](https://repost.aws/knowledge-center/malformed-502-api-gateway)。