When an application runs behind Amazon CloudFront, diagnosing HTTPS connection problems can be difficult. A user may report that a website works on one network but fails on another. Some users may experience slow connections, while others may encounter intermittent TLS handshake failures.
The problem is not always in the application server. It can originate from the viewer's browser, TLS implementation, internet service provider, or network configuration.
Amazon CloudFront provides viewer-related HTTP headers that help developers understand how a request reached the distribution. Among these are TLS-related headers containing information about the negotiated protocol, cipher suite, and handshake. CloudFront also provides viewer ISP information and additional TLS details that help investigate network and cryptographic compatibility.
These headers can be forwarded to the origin server or inspected at the edge, making them useful for troubleshooting without implementing custom TLS packet inspection.
This article explains how CloudFront TLS headers work, how to configure them, and how to use the information in an application to investigate HTTPS connection problems.
Understanding CloudFront Viewer TLS Headers
CloudFront terminates the viewer's HTTPS connection at its edge location. It then communicates with the configured origin using a separate connection.
This distinction is important because the TLS connection between the viewer and CloudFront is not necessarily the same as the connection between CloudFront and the origin.
For example:
- A browser connects to CloudFront using TLS 1.3.
- CloudFront connects to an application server using TLS 1.2.
- The application receives the original viewer's TLS information through a forwarded HTTP header.
Without this information, an origin server generally sees the CloudFront connection rather than the original viewer's TLS negotiation.
CloudFront provides headers that help bridge this visibility gap.
CloudFront-Viewer-TLS
The CloudFront-Viewer-TLS header contains three pieces of information:
- TLS protocol version.
- Negotiated cipher suite.
- TLS handshake information.
Its format is:
TLS_VERSION:CIPHER_SUITE:HANDSHAKE_INFORMATION
For example:
TLSv1.3:TLS_AES_128_GCM_SHA256:sessionResumed
This indicates that the viewer used TLS 1.3, negotiated the AES-128-GCM cipher suite, and resumed an existing TLS session.
The handshake information can have the following values:
| Value | Meaning |
|---|
| fullHandshake | A complete TLS handshake was performed |
| sessionResumed | An existing TLS session was resumed |
| connectionReused | An existing TLS connection was reused |
This information helps developers distinguish connection behavior when investigating TLS-related performance issues.
CloudFront-Viewer-ISP
The CloudFront-Viewer-ISP header contains the name of the viewer's internet service provider.
It can help identify whether connection problems are concentrated among users accessing an application through a particular network provider.
For example, if users from one ISP experience repeated connection failures while users from other networks access the application successfully, the ISP information can help narrow the investigation.
This is especially useful for applications serving users across multiple countries and network providers.
The ISP header provides network attribution, not proof that the ISP is responsible for the problem.
CloudFront-Viewer-TLS-Details
The CloudFront-Viewer-TLS-Details header provides additional information about the cryptographic negotiation between the viewer and CloudFront.
It includes:
- TLS version.
- Cipher suite.
- Handshake type.
- Key exchange algorithm.
- Signature scheme.
- Signature public key type.
The value is represented as a JSON object.
For example:
{
"tlsVersion": "TLSv1.3",
"cipherSuite": "TLS_AES_128_GCM_SHA256",
"handshakeType": "fullHandshake",
"keyExchange": "X25519MLKEM768",
"signatureScheme": "ecdsa_secp256r1_sha256",
"signaturePublicKeyType": "ECDSA"
}
This example illustrates the structure and a possible combination of cryptographic details. Actual values depend on the negotiated connection.
One important use is identifying whether the connection used a post-quantum key exchange.
Developers can use this information to understand cryptographic compatibility and measure the adoption of newer TLS capabilities.
How These Headers Help Troubleshoot HTTPS Problems
Different TLS headers answer different questions during an investigation.
| Header | Information provided | Troubleshooting use |
|---|
| CloudFront-Viewer-TLS | TLS version, cipher, handshake type | Identify protocol and cipher compatibility |
| CloudFront-Viewer-ISP | Viewer internet service provider | Compare network-specific failures |
| CloudFront-Viewer-TLS-Details | Key exchange and signature details | Investigate cryptographic compatibility |
| CloudFront-Viewer-JA3-Fingerprint | TLS client fingerprint | Identify unusual client patterns |
| CloudFront-Viewer-JA4-Fingerprint | Additional TLS client fingerprint | Analyze client behavior and traffic patterns |
These headers provide useful diagnostic information, but they do not replace browser console errors, CloudFront access logs, origin logs, or application monitoring.
Configuring TLS Headers in Amazon CloudFront
CloudFront does not automatically forward every viewer-related header to the origin.
You must configure an origin request policy to include the headers your application needs.
Step 1: Open the CloudFront Distribution
Sign in to the AWS Management Console.
Navigate to CloudFront and select the distribution that serves your application.
Open the Behaviors tab and identify the cache behavior associated with the application endpoint.
For example, if your application uses /api/*, select the behavior that handles API requests.
Step 2: Create an Origin Request Policy
Open the origin request policy configuration and create a custom policy.
Choose the header forwarding option that allows you to specify individual headers.
Add the following headers:
CloudFront-Viewer-TLS
CloudFront-Viewer-ISP
CloudFront-Viewer-TLS-Details
You can also add JA3 and JA4 fingerprint headers if your application needs client fingerprint information.
Avoid forwarding every available viewer header without a clear requirement. Forwarding only the required values keeps the request configuration easier to manage.
Step 3: Attach the Policy to the Cache Behavior
Save the origin request policy and attach it to the selected cache behavior.
An origin request policy forwards selected headers to the origin without automatically adding them to the cache key.
This distinction matters.
TLS and ISP information is useful for diagnostics, but it normally should not create separate cached copies of the same application response.
If an application genuinely returns different content based on a forwarded header, review the cache-key design carefully to avoid serving an incorrect response to another viewer.
Step 4: Deploy and Verify the Configuration
Save the distribution changes and wait until the distribution deployment completes.
Send a new HTTPS request through CloudFront and inspect the corresponding request at the origin.
The expected headers should be available when CloudFront forwards them.
Remember that these headers describe the viewer-to-CloudFront connection, not the CloudFront-to-origin TLS connection.
Reading CloudFront TLS Headers in a Node.js Application
Once CloudFront forwards the headers, an application can capture them for diagnostics.
The following Express.js example reads the TLS version, cipher suite, handshake information, and ISP.
const express = require("express");
const app = express();
app.get("/api/connection-info", (req, res) => {
const tlsHeader =
req.get("CloudFront-Viewer-TLS");
const isp =
req.get("CloudFront-Viewer-ISP");
const tlsDetailsHeader =
req.get("CloudFront-Viewer-TLS-Details");
let tlsDetails = null;
try {
if (tlsDetailsHeader) {
tlsDetails = JSON.parse(tlsDetailsHeader);
}
} catch (error) {
console.error("Invalid TLS details header");
}
const tlsParts = tlsHeader
? tlsHeader.split(":")
: [];
res.json({
tlsVersion: tlsParts[0] || "Unknown",
cipherSuite: tlsParts[1] || "Unknown",
handshakeType: tlsParts[2] || "Unknown",
isp: isp || "Unknown",
tlsDetails
});
});
app.listen(3000, () => {
console.log("Application started");
});
The endpoint returns diagnostic information in a structured JSON response.
For example:
{
"tlsVersion": "TLSv1.3",
"cipherSuite": "TLS_AES_128_GCM_SHA256",
"handshakeType": "sessionResumed",
"isp": "Example Network",
"tlsDetails": {
"tlsVersion": "TLSv1.3",
"keyExchange": "X25519"
}
}
The response is illustrative.
In a production application, avoid exposing detailed connection information through a publicly accessible endpoint. Store the information in application logs or a restricted diagnostic service instead.
Also, do not assume that a forwarded header is trustworthy if users can access the origin directly. Restrict origin access to CloudFront and ensure that the application only trusts headers supplied through the intended distribution path.
Using TLS Information to Investigate Connection Problems
Let's consider a practical example.
An application receives reports that users from one network provider experience intermittent HTTPS connection problems.
The development team can collect the viewer ISP and TLS information for successful requests and compare it with CloudFront access logs and application logs.
A simplified investigation might look like this:
| Observation | Possible investigation |
|---|
| Failures concentrated around one ISP | Review network routing and provider-specific connectivity |
| Older TLS versions appear frequently | Review the distribution's minimum TLS security policy |
| Different cipher suites appear across clients | Check client and browser compatibility |
| Unexpected TLS handshake patterns | Review connection reuse and client behavior |
| Different key exchange algorithms | Investigate cryptographic compatibility |
| Requests associated with unusual JA3 or JA4 fingerprints | Investigate automated or unexpected clients |
There is an important limitation: these headers are available only after CloudFront has established an HTTP request from the viewer.
If a TLS handshake fails before HTTP communication is established, the request cannot reach the origin with these headers.
For those failures, use CloudFront monitoring, client-side diagnostics, and other available connection-level evidence.
Troubleshooting Common Configuration Problems
TLS headers are missing at the origin
First, verify that the headers are included in the origin request policy attached to the correct cache behavior.
Also confirm that the distribution deployment has completed.
ISP information is unavailable
Check whether the request is coming from an expected viewer network and whether the relevant header is configured.
ISP information may not be sufficient to identify the organization behind every network address.
TLS details cannot be parsed
The TLS details header contains JSON. Check the raw value before parsing it.
Use error handling so malformed or missing diagnostic information does not break the main application request.
CloudFront and origin TLS versions are different
This is expected in some architectures.
The viewer-to-CloudFront connection and CloudFront-to-origin connection are separate TLS sessions.
Inspect the correct connection when investigating a protocol mismatch.
Origin receives unexpected header values
Review whether the origin can be accessed directly and whether client-supplied headers can reach application logic.
Use origin access restrictions and trusted CloudFront forwarding configuration to prevent untrusted values from being treated as authoritative.
Best Practices for Production Applications
- Forward only the headers required for troubleshooting and monitoring.
- Use an origin request policy when the information is needed at the origin but should not affect the cache key.
- Record TLS version, cipher suite, and ISP alongside request IDs and timestamps.
- Avoid storing sensitive diagnostic information longer than necessary.
- Restrict direct access to the origin server.
- Validate forwarded header values before using them in application logic.
- Compare TLS information with CloudFront access logs and application errors.
- Monitor connection patterns across different network providers.
- Use JA3 and JA4 fingerprints as supporting signals rather than treating them as proof of malicious activity.
- Keep the viewer-to-CloudFront and CloudFront-to-origin TLS configurations separate during investigations.
Advantages and Disadvantages of CloudFront TLS Headers
Advantages
- Provide visibility into the TLS connection negotiated by viewers.
- Help identify differences in TLS versions and cipher suites.
- Support ISP-based troubleshooting.
- Provide additional information about cryptographic key exchange.
- Can be inspected by the origin application or supported edge functions.
- Help security teams investigate unusual client connection patterns.
Disadvantages
- Do not provide information about TLS handshakes that fail before an HTTP request is established.
- Require origin request policy configuration when forwarding headers to the origin.
- Do not independently identify the root cause of network failures.
- Require careful handling to avoid trusting unverified headers.
- Additional logging can increase storage and monitoring costs.
Summary
Amazon CloudFront provides several viewer-related headers that help developers investigate HTTPS connection behavior.
The CloudFront-Viewer-TLS header identifies the negotiated TLS version, cipher suite, and handshake information. CloudFront-Viewer-ISP helps compare requests across network providers, while CloudFront-Viewer-TLS-Details provides additional cryptographic information, including key exchange and signature details.
By configuring an origin request policy, developers can forward these values to their application and include them in diagnostic logs.
These headers are particularly useful when investigating client compatibility, network-specific problems, and cryptographic migration. However, they cannot explain every connection failure, especially failures that occur before the TLS handshake completes.
Combining CloudFront headers with access logs, application monitoring, and origin security controls provides a more complete approach to troubleshooting HTTPS connections in production.
Join the conversation! Your thoughts help the community grow.