Ssl

Changelog

import { ProductChangelog } from "~/components";

{/* <!-- Actual content lives in /src/content/changelog/ssl. Update the file there for new entries to appear here. */}

2024-10-18

New cloudflare_branding flag allows hostnames with over 64 characters for all CAs

To order certificates for hostnames longer than 64 characters, customers can now use the cloudflare_branding flag when ordering a certificate via API. Setting cloudflare_branding to true will cause sni.cloudflaressl.com to be used as the common name, while the long hostname is added as part of the subject alternative name (SAN).

2024-09-19

SSL.com available with ACM and SSL for SaaS

SSL.com is one of the certificate authorities that Cloudflare partners with. SSL.com is now available as an option to customers with Advanced Certificate Manager (ACM) or SSL for SaaS. Consider our reference documentation for details.

Concepts

import { Stream, Render } from "~/components";

This page defines and articulates key concepts that are relevant to Cloudflare SSL/TLS and are used in this documentation. For more concepts and broader descriptions, check out the Cloudflare Learning Center.

SSL/TLS certificate

An SSL/TLS certificate is what enables websites and applications to establish secure connections. With SSL/TLS, a client - such as a browser - can verify the authenticity and integrity of the server it is connecting with, and use encryption to exchange information.

Since Cloudflare's global network is at the core of several products and services that Cloudflare offers, what this implies in terms of SSL/TLS is that, instead of only one certificate, there can actually be two certificates involved in a single request: an edge certificate and an origin certificate.

Edge certificate

The edge certificates are the ones that Cloudflare presents to clients visiting your website or application. You can manage edge certificates through the Cloudflare Dashboard.

Origin certificate

Origin certificates guarantee the security and authentication on the other side of the network, between Cloudflare and the origin server of your website or application. Origin certificates are managed on your origin server.

SSL/TLS encryption modes control whether and how Cloudflare will use both these certificates, and you can choose between different modes on the SSL/TLS overview page.

Validity period

One common aspect of every SSL/TLS certificate is that they must have a fixed expiration date. If a certificate is expired, clients - such as your visitor's browser - will consider that a secure connection cannot be established, resulting in warnings or errors.

Different certificate authorities (CAs) support different validity periods. Cloudflare works with them to guarantee that both Universal and Advanced edge certificates are always renewed.

Certificate authority (CA)

A certificate authority (CA) is a trusted third party that generates and gives out SSL/TLS certificates. The CA digitally signs the certificates with their own private key, allowing client devices - such as your visitor's browser - to verify that the certificate is trustworthy.

As explained in the article about what is an ssl certificate, this means that, besides not being expired, an SSL/TLS certificate should be issued by a certificate authority (CA) in order to avoid warnings or errors.

Validation level

SSL/TLS certificates vary in terms of the level to which a CA has validated them. As explained in the article about types of certificates, SSL/TLS certificates can be DV (Domain Validated), OV (Organization Validated) or EV (Extended Validation).


Origin pull

When visitors request content from your website or application, Cloudflare first attempts to serve content from the cache. If this attempt fails, Cloudflare sends a request back to your origin web server to get the content. This request between Cloudflare and your origin web server is called origin pull.

This relates to the difference between edge certificates and origin certificates, and also explains why some specifications such as cipher suites can be set differently depending on whether they refer to the connection between Cloudflare and your visitor's browser or between Cloudflare and your origin server.

Cipher suites

Besides the authentication and integrity aspects that valid certificates guarantee, the other important aspect of SSL/TLS certificates is encryption. Cipher suites determine the set of algorithms that can be used for encryption/decryption and that will be negotiated during an SSL/TLS handshake.

For the purpose of this documentation, keep in mind that cipher suites supported at Cloudflare's network may not be the same as cipher suites presented by Cloudflare to your origin server.

Trust store

The list of certificate authority (CA) and intermediate certificates that are trusted by operating systems, web browsers or other software that interacts with SSL/TLS certificates is called trust store. Cloudflare maintains its trust store on a public GitHub repository.

While for most cases you do not have to worry about this list or how it is used when a client checks your SSL/TLS certificate, some features such as Custom Origin Trust Store, and processes such as bundle methodologies, are directly related to it.

Chain of trust

Depending on your organization requirements, or if you have to troubleshoot an issue with your certificates, for example, you might come across the terms root certificate, intermediate certificate and leaf certificate.

These terms refer to the way in which the certificate presented to a client - the leaf certificate - has to be traceable back to a trusted certificate authority (CA) certificate - the root certificate. This process is structured around a chain of trust.

SSL/TLS FAQ

import { Render } from "~/components";

Refer to this page for frequently asked questions about Cloudflare SSL/TLS certificate offerings and the CAs that Cloudflare partners with.


General

Does Cloudflare issue both RSA and ECDSA certificates?

Yes. Cloudflare can issue both RSA and ECDSA certificates.

Are Cloudflare SSL certificates shared?

No. Cloudflare SSL/TLS certificates are not shared across domains nor across customers.

If I have multiple Cloudflare certificates, which one is used?

Cloudflare certificates are prioritized by a combination of hostname specificity, zone specificity, and certificate type. For more details, refer to Certificate and hostname priority.

Why do I see a Cloudflare certificate when an SSL certificate is installed at my website?

Cloudflare must decrypt traffic in order to cache and filter malicious traffic. Cloudflare either re-encrypts traffic or sends plain text traffic to the origin web server depending on your domain's encryption mode.


Certificate authorities (CAs)

Which certificate authorities does Cloudflare use?

Cloudflare uses Let's Encrypt, Google Trust Services, SSL.com, and Sectigo. You can see a complete list of products and available CAs and algorithms in the certificate authorities reference page.

Sectigo is only used for backup certificates.

Are there any CA limitations I should know about?

Refer to the certificate authorities reference page for a list of limitations for every CA in our pipeline. There you can also find information about device and browser compatibility.

I do not want to use the CAs that Cloudflare partners with. What can I do?

If you are on a Business or Enterprise plan, you can upload a certificate from the CA of your choice.

I am missing the CAs that Cloudflare uses in my trust store. What should I do?

You can use CFSSL trust store, which includes all of the CAs that are used by Cloudflare managed certificates.


CAA records

What is CAA and how can I create one?


For more details, refer to Add CAA records.

How does Cloudflare evaluate CAA records?

CAA records are evaluated by a CA, not by Cloudflare. For details, refer to RFC 8659.

Setting a CAA record to specify one or more particular CAs does not affect which CA Cloudflare uses to issue universal or advanced certificates for your domain. If you wish, you can specify CAs associated with Cloudflare certificates when ordering an advanced certificate.

What are the dangers of setting CAA records?

If you are part of a large organization or one where multiple parties are tasked with obtaining SSL certificates, include CAA records that allow issuance for all CAs applicable for your organization. Failure to do so can inadvertently block SSL issuance for other parts of your organization.

What CAA records do I need to allow issuance from Cloudflare CAs?

You can find CAA records associated with every Cloudflare CA in the certificate authorities reference page. If you are using Cloudflare as your DNS provider, then the CAA records will be added on your behalf.


Universal SSL

I am using Universal SSL and I would like to use a different CA. How can I do that?

To be able to specify a CA, you must purchase Advanced Certificate Manager. Through Advanced Certificate Manager, you can choose the certificate authority when ordering an advanced certificate or you can choose a default CA when using Total TLS.

If you are on a Business or Enterprise plan, you can upload a certificate from the CA of your choice. In this case, certificate issuance and renewal will have to be managed by you.

Does Cloudflare issue both RSA and ECDSA certificates for Universal certificates?

Universal certificates on free zones only receive an ECDSA certificate. Paid zones receive an RSA and ECDSA certificate.

RSA certificate missing after upgrading from Free to a paid plan

When you upgrade your zone from the Free plan to a paid plan, Cloudflare does not automatically re-issue your Universal SSL certificate. Your existing ECDSA-only certificate continues to serve until the certificate pack next renews. At renewal, Cloudflare issues both an RSA and an ECDSA certificate.

If you need an RSA certificate before the next renewal, you can:

For more details, refer to Certificate type.

Get started

import { GlossaryDefinition, Render } from "~/components";

Set up encrypted connections for your domain by choosing a certificate, selecting an encryption mode, and enforcing HTTPS.

Before you begin

Choose an edge certificate

Edge certificates are the SSL/TLS certificates that Cloudflare presents to visitors connecting to your domain. Cloudflare offers several types:

For help deciding which certificate type fits your use case, refer to Edge certificates.

:::note[For SaaS providers]

For more details, refer to Cloudflare for SaaS (managed hostnames).

:::

Choose your encryption mode

Once you have chosen your edge certificate, choose an encryption mode.

Encryption modes control how Cloudflare manages two separate connections: one between visitors and Cloudflare, and another between Cloudflare and your origin server. Modes range from no encryption to strict validation of your origin certificate. For more context, refer to the concepts page.

Full (strict) mode — the most secure option — requires a valid, unexpired certificate on your origin server. You can use a certificate from a publicly trusted certificate authority (CA), or generate a free Origin CA certificate from Cloudflare. Each encryption mode page lists its specific requirements.

Enforce HTTPS connections

SEO considerations

Using HTTPS can improve user trust and may be used as a ranking signal by search engines. For related guidance, refer to Improve SEO.

Optional - Enable additional features

Cloudflare SSL/TLS

import { Description, Feature, Plan, RelatedProduct } from "~/components";

Encrypt your web traffic to prevent data theft and other tampering.

SSL/TLS certificates encrypt traffic between visitors and your website, preventing eavesdropping and data tampering. Because Cloudflare sits between your visitors and your origin server, two certificates can be involved in a single request: an edge certificate (visitor to Cloudflare) and an origin certificate (Cloudflare to your server).

Cloudflare automatically issues free certificates through Universal SSL and offers additional options for custom certificate management. Refer to Get started to set up SSL/TLS for your domain.


Features

<Feature header="Total TLS" href="/ssl/edge-certificates/additional-options/total-tls/"

Universal SSL covers your apex domain and first-level subdomains. Total TLS
extends that coverage by automatically issuing certificates for proxied
hostnames at any subdomain level.

<Feature header="Delegated DCV" href="/ssl/edge-certificates/changing-dcv-method/methods/delegated-dcv/"

Before issuing a certificate, a certificate authority (CA) must verify you
control the domain. If you manage DNS outside of Cloudflare, you can delegate
this verification to Cloudflare so certificate renewals happen automatically.

<Feature header="Custom TLS settings" href="/ssl/edge-certificates/additional-options/minimum-tls/"

Specify the minimum TLS version that visitors must use to connect to your
website or application, and [restrict cipher
suites](/ssl/edge-certificates/additional-options/cipher-suites/customize-cipher-suites/)
to meet compliance or security requirements.

When you use Cloudflare DNS, all DNS queries for your domain are answered by Cloudflare's global anycast network. This network delivers performance and global availability.

<RelatedProduct header="Cloudflare for SaaS" href="/cloudflare-for-platforms/cloudflare-for-saas/" product="cloudflare-for-platforms"

Cloudflare for SaaS allows you to extend the security and performance benefits
of Cloudflare's network to your customers via their own custom or vanity
domains.

Bring your own CA for mTLS

import { APIRequest, Render, TabItem, Tabs, DashButton } from "~/components";

This page explains how you can manage client certificates that have not been issued by Cloudflare CA. For a broader overview, refer to the mTLS at Cloudflare learning path.

Bring your own CA (BYOCA) is especially useful if you already have mTLS implemented and client certificates are already installed on devices.

Availability

:::note If you exceed the CA certificate quota, the API returns error 1489 with the message "Hit maximum CA cert allocation." Contact your account team to request a quota increase. :::

:::note[Cloudflare Access uses a separate quota] CAs uploaded through Cloudflare Access use a separate quota that is not counted against the five-CA limit. If you see error 12130 ("maximum number of certificates has been reached") in Access, this relates to the Access certificate quota, not the BYOCA CA quota. :::

When to use BYOCA

BYOCA works well if:

If you only have a small, stable set of devices or services to authenticate, the Cloudflare-managed CA is simpler to set up.

CA certificate requirements

When you upload your CA, Cloudflare validates the certificate according to certain requirements.

:::note Uploading the CA private key is only required if you wish to use Zero Trust's block page. To upload your own CA with the private key, use the Upload mTLS certificate endpoint. :::

Set up mTLS with your CA

If your client certificates are issued by an intermediate CA, upload the full CA chain (the Intermediate CA followed by the Root CA) in a single PEM file. Refer to Upload the CA certificate, not a leaf certificate.

  1. In the Cloudflare dashboard, go to the Client Certificates page.

  2. Select Add Certificate.

  3. In the Certificate Authority dropdown, select Bring your own CA.

  4. Upload your CA certificate file (PEM encoded) and enter a name for the CA.

  5. Select Continue.

  6. On the Associate Hostnames page, enter the hostname that should use this CA for mTLS validation and select Add for each one. You can also skip this step and associate hostnames later.

  7. Select Save to confirm.

  1. Use the Upload mTLS certificate endpoint to upload the CA root certificate.
  1. Take note of the certificate ID (id) that is returned in the API response.
  2. Use the Replace Hostname Associations endpoint to enable mTLS in each hostname that should use the CA for mTLS validation. Use the following parameters:
  1. (Optional) Make a GET request to confirm the CA hostname associations.

After uploading the CA and associating hostnames, create a custom rule to enforce client certificate validation. You can do this via the dashboard or via API.

  "expression": "(http.host in {\"<HOSTNAME_1>\" \"<HOSTNAME_2>\"} and not cf.tls_client_auth.cert_verified)",
  "action": "block"

:::note When using CNAME records, enforce mTLS on the specific hostname where it should be checked. It is not enough to have it set on the CNAME target. :::

Multiple CAs for one hostname

There can be multiple CAs (Cloudflare-managed or BYOCA) associated with the same hostname. For BYOCA certificates, the most recently deployed certificate will be prioritized.

If you wish to remove the association from the Cloudflare-managed certificate and only use your BYOCA certificate(s):

  1. In the Cloudflare dashboard, go to the Client Certificates page.

  2. On the Hosts section under Cloudflare-issued Client Certificates, select Edit.

  3. Select the cross next to the hostname you want to remove.

  4. Select Save to confirm.

  1. List the hostname associations without the mtls_certificate_id parameter.

  1. Copy the hostnames array returned by the API and update it, removing the hostname that should no longer use the Cloudflare-managed CA.
  2. Use the Replace Hostname Associations endpoint without the mtls_certificate_id parameter to perform the action against the Cloudflare-managed CA. For hostnames use the list from the previous step.

<APIRequest path="/zones/{zone_id}/certificate_authorities/hostname_associations" method="PUT" json={{ hostnames: ["<UPDATED_HOSTNAME_ASSOCIATIONS>"], }} />

Delete an uploaded CA

If you want to remove a CA that you have previously uploaded, you must first remove any hostname associations that it has.

  1. In the Cloudflare dashboard, go to the Client Certificates page.

  2. Select the BYOCA tab.

  3. Find the CA you want to delete and select the three dots next to it.

  4. Remove all associated hostnames first, if any exist.

  5. Select the delete option and confirm.

  1. Make a request to the Replace Hostname Associations endpoint, with an empty array for hostnames and specifying your CA certificate ID in mtls_certificate_id:
  "hostnames": [],
  "mtls_certificate_id": "<CERTIFICATE_ID>"
  1. Use the Delete mTLS certificate endpoint to delete the certificate.

List CA hostname associations

  1. In the Cloudflare dashboard, go to the Client Certificates page.

  2. Select the BYOCA tab.

  3. Find the CA you want to inspect and select the three dots next to it.

  4. Select Edit hostnames. The Certificate Details panel displays the associated hostnames.

Use the List Hostname Associations endpoint with the mtls_certificate_id query parameter set to the certificate ID of the uploaded CA.

<APIRequest path="/zones/{zone_id}/certificate_authorities/hostname_associations" method="GET" parameters={{ mtls_certificate_id: "ID_FROM_STEP_2", }} />

Client certificate variables

When a request includes a client certificate for mTLS authentication, Cloudflare exposes certificate details as variables in the Ruleset Engine and as properties on the Workers request.cf object.

Ruleset Engine fields

Client certificate fields are available as mTLS fields in Ruleset Engine-based products such as WAF custom rules and request header modification rules.

Workers variables

These variables are also available as part of the request.cf.tlsClientAuth object via Cloudflare Workers. Refer to the linked Rules language field for the full definition.

:::note Some tlsClientAuth properties have a different type than their Rules language field equivalent. Those differences are called out in the following list. :::

Configure your mobile app or IoT device

This tutorial demonstrates how to configure your Internet-of-things (IoT) device and mobile application to use client certificates with API Shield.

Scenario details

This walkthrough uses the example of a device that captures temperature readings and transmits them by sending a POST request to a Cloudflare-protected API. A mobile application built in Swift for iOS retrieves those readings and displays them.

To keep this example simple, the API is implemented as a Cloudflare Worker (borrowing code from the To-Do List tutorial on building a jamstack app).

Temperatures are stored in Workers KV using the source IP address as a key, but you can easily use a value from the client certificate, such as the fingerprint.

The example API code below saves a temperature and timestamp into KV when a POST is made and returns the most recent five temperatures when a GET request is made.

const defaultData = { temperatures: [] };

const getCache = (key) => TEMPERATURES.get(key);
const setCache = (key, data) => TEMPERATURES.put(key, data);

async function addTemperature(request) {
	// Pull previously recorded temperatures for this client.
	const ip = request.headers.get("CF-Connecting-IP");
	const cacheKey = `data-${ip}`;
	let data;
	const cache = await getCache(cacheKey);
	if (!cache) {
		await setCache(cacheKey, JSON.stringify(defaultData));
		data = defaultData;
	} else {
		data = JSON.parse(cache);
	}

	// Append the recorded temperatures with the submitted reading (assuming it has both temperature and a timestamp).
	try {
		const body = await request.text();
		const val = JSON.parse(body);

		if (val.temperature && val.time) {
			data.temperatures.push(val);
			await setCache(cacheKey, JSON.stringify(data));
			return new Response("", { status: 201 });
		} else {
			return new Response(
				"Unable to parse temperature and/or timestamp from JSON POST body",
				{ status: 400 },
			);
		}
	} catch (err) {
		return new Response(err, { status: 500 });
	}
}

function compareTimestamps(a, b) {
	return -1 * (Date.parse(a.time) - Date.parse(b.time));
}

// Return the 5 most recent temperature measurements.
async function getTemperatures(request) {
	const ip = request.headers.get("CF-Connecting-IP");
	const cacheKey = `data-${ip}`;

	const cache = await getCache(cacheKey);
	if (!cache) {
		return new Response(JSON.stringify(defaultData), {
			status: 200,
			headers: { "content-type": "application/json" },
		});
	} else {
		data = JSON.parse(cache);
		const retval = JSON.stringify(
			data.temperatures.sort(compareTimestamps).splice(0, 5),
		);
		return new Response(retval, {
			status: 200,
			headers: { "content-type": "application/json" },
		});
	}
}

export default {
	async fetch(request, env, ctx) {
		return request.method === "POST"
			? addTemperature(request)
			: getTemperatures(request);
	},
};

1. Validate API

POST sample data to API

To validate the API before adding mTLS authentication, POST a random temperature reading:

$ TEMPERATURE=$(echo $((361 + RANDOM %11)) | awk '{printf("%.2f",$1/10.0)}')
$ TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

$ echo -e "$TEMPERATURE\n$TIMESTAMP"
36.70
2020-09-28T02:54:56Z

$ curl --verbose --header "Content-Type: application/json" --data '{"temperature":'''$TEMPERATURE''', "time": "'''$TIMESTAMP'''"}' https://shield.upinatoms.com/temps 2>&1 | grep "< HTTP/2"
< HTTP/2 201

GET sample data from API

A GET request to the temps endpoint returns the most recent readings, including the one submitted in the example above:

$ curl --silent https://shield.upinatoms.com/temps | jq .
[
  {
    "temperature": 36.3,
    "time": "2020-09-28T02:57:49Z"
  },
  {
    "temperature": 36.7,
    "time": "2020-09-28T02:54:56Z"
  },
  {
    "temperature": 36.2,
    "time": "2020-09-28T02:33:08Z"
  }
]

2. Create Cloudflare-issued certificates

Before you can use API Shield to protect your API or web application, create Cloudflare-issued client certificates.

You can create a client certificate in the Cloudflare dashboard.

However, since most developers working at scale generate their own private keys and certificate signing requests via API, this example uses the Cloudflare API to create client certificates.

To create a bootstrap certificate for the iOS application and the IoT device, this example uses Cloudflare’s public key infrastructure toolkit, CFSSL:

# Generate a private key and CSR for the iOS device.

$ cat <<'EOF' | tee -a csr.json
{
    "hosts": [
        "ios-bootstrap.devices.upinatoms.com"
    ],
    "CN": "ios-bootstrap.devices.upinatoms.com",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [{
        "C": "US",
        "L": "Austin",
        "O": "Temperature Testers, Inc.",
        "OU": "Tech Operations",
        "ST": "Texas"
    }]
}
EOF

$ cfssl genkey csr.json | cfssljson -bare certificate

2020/09/27 21:28:46 [INFO] generate received request
2020/09/27 21:28:46 [INFO] received CSR
2020/09/27 21:28:46 [INFO] generating key: rsa-2048
2020/09/27 21:28:47 [INFO] encoded CSR

$ mv certificate-key.pem ios-key.pem
$ mv certificate.csr ios.csr

# Do the same for the IoT sensor.

$ sed -i.bak 's/ios-bootstrap/sensor-001/g' csr.json
$ cfssl genkey csr.json | cfssljson -bare certificate
...
$ mv certificate-key.pem sensor-key.pem
$ mv certificate.csr sensor.csr

# now ask that these CSRs be signed by the private CA issued for your zone
# we need to replace actual newlines in the CSR with ‘\n’ before POST’ing
$ CSR=$(cat ios.csr | perl -pe 's/\n/\\n/g')
$ request_body=$(< <(cat <<EOF
{
  "validity_days": 3650,
  "csr":"$CSR"
}
EOF
))

# save the response so we can view it and then extra the certificate
$ curl https://api.cloudflare.com/client/v4/zones/{zone_id}/client_certificates \
--header "X-Auth-Email: <EMAIL>" \
--header "X-Auth-Key: <API_KEY>" \
--header "Content-Type: application/json" \
--data "$request_body" > response.json

$ cat response.json | jq .

{
  "success": true,
  "errors": [],
  "messages": [],
  "result": {
    "id": "7bf7f70c-7600-42e1-81c4-e4c0da9aa515",
    "certificate_authority": {
      "id": "8f5606d9-5133-4e53-b062-a2e5da51be5e",
      "name": "Cloudflare Managed CA for account 11cbe197c050c9e422aaa103cfe30ed8"
    },
    "certificate": "-----BEGIN CERTIFICATE-----\nMIIEkzCCA...\n-----END CERTIFICATE-----\n",
    "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIIDITCCA...\n-----END CERTIFICATE REQUEST-----\n",
    "ski": "eb2a48a19802a705c0e8a39489a71bd586638fdf",
    "serial_number": "133270673305904147240315902291726509220894288063",
    "signature": "SHA256WithRSA",
    "common_name": "ios-bootstrap.devices.upinatoms.com",
    "organization": "Temperature Testers, Inc.",
    "organizational_unit": "Tech Operations",
    "country": "US",
    "state": "Texas",
    "location": "Austin",
    "expires_on": "2030-09-26T02:41:00Z",
    "issued_on": "2020-09-28T02:41:00Z",
    "fingerprint_sha256": "84b045d498f53a59bef53358441a3957de81261211fc9b6d46b0bf5880bdaf25",
    "validity_days": 3650
  }
}

$ cat response.json | jq .result.certificate | perl -npe 's/\\n/\n/g; s/"//g' > ios.pem

# Now ask that the second client certificate signing request be signed.

$ CSR=$(cat sensor.csr | perl -pe 's/\n/\\n/g')
$ request_body=$(< <(cat <<EOF
{
  "validity_days": 3650,
  "csr":"$CSR"
}
EOF
))

$ curl https://api.cloudflare.com/client/v4/zones/{zone_id}/client_certificates \
--header "X-Auth-Email: <EMAIL>" \
--header "X-Auth-Key: <API_KEY>" \
--header "Content-Type: application/json" \
--data "$request_body" | perl -npe 's/\\n/\n/g; s/"//g' > sensor.pem

3. Embed the client certificate in your mobile app

To configure the mobile app to securely request temperature data submitted by the IoT device, embed the client certificate in the mobile app.

For simplicity, this example embeds a “bootstrap” certificate and key in the application bundle as a PKCS#12-formatted file:

$ openssl pkcs12 -export -out bootstrap-cert.pfx -inkey ios-key.pem -in ios.pem
Enter Export Password:
Verifying - Enter Export Password:

In a real-world deployment, a bootstrap certificate should only be used in conjunction with users' credentials to authenticate with an API endpoint that can return a unique user certificate. Corporate users will want to use mobile device management (MDM) to distribute certificates.

Embed the client certificate in an Android app

The following is an example of how you may use a client certificate in an Android app to make HTTP calls. You need to add the following permission in AndroidManifest.xml to allow an Internet connection.

<uses-permission android:name="android.permission.INTERNET" />

For demonstration purposes, the certificate in this example is stored in app/src/main/res/raw/cert.pem and the private key is stored in app/src/main/res/raw/key.pem. You may also store these files in other secure manners.

The following example uses an OkHttpClient, but you may also use other clients such as HttpURLConnection in similar ways. The key is to use the SSLSocketFactory.

private OkHttpClient setUpClient() {
    try {
        final String SECRET = "secret"; // You may also store this String somewhere more secure.
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

        // Get private key
        InputStream privateKeyInputStream = getResources().openRawResource(R.raw.key);
        byte[] privateKeyByteArray = new byte[privateKeyInputStream.available()];
        privateKeyInputStream.read(privateKeyByteArray);

        String privateKeyContent = new String(privateKeyByteArray, Charset.defaultCharset())
                .replace("-----BEGIN PRIVATE KEY-----", "")
                .replaceAll(System.lineSeparator(), "")
                .replace("-----END PRIVATE KEY-----", "");

        byte[] rawPrivateKeyByteArray = Base64.getDecoder().decode(privateKeyContent);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(rawPrivateKeyByteArray);

        // Get certificate
        InputStream certificateInputStream = getResources().openRawResource(R.raw.cert);
        Certificate certificate = certificateFactory.generateCertificate(certificateInputStream);

        // Set up KeyStore
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, SECRET.toCharArray());
        keyStore.setKeyEntry("client", keyFactory.generatePrivate(keySpec), SECRET.toCharArray(), new Certificate[]{certificate});
        certificateInputStream.close();

        // Set up Trust Managers
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init((KeyStore) null);
        TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();

        // Set up Key Managers
        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManagerFactory.init(keyStore, SECRET.toCharArray());
        KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();

        // Obtain SSL Socket Factory
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyManagers, trustManagers, new SecureRandom());
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

        // Finally, return the client, which will then be used to make HTTP calls.
        OkHttpClient client = new OkHttpClient.Builder()
                .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustManagers[0])
                .build();

        return client;

    } catch (CertificateException | IOException | NoSuchAlgorithmException | KeyStoreException | UnrecoverableKeyException | KeyManagementException | InvalidKeySpecException e) {
        e.printStackTrace();
        return null;
    }
}

The above function returns an OkHttpClient embedded with the client certificate. You can now use this client to make HTTP requests to your API endpoint protected with mTLS.


4. Embed the client certificate on your IoT device

To prepare the IoT device for secure communication with the API endpoint, embed the certificate on the device and configure the device to use the certificate when making POST requests.

This example assumes the certificate and the private key are securely copied to /etc/ssl/private/sensor-key.pem and /etc/ssl/certs/sensor.pem.

The sample script is modified to point to these files:

import requests
import json
from datetime import datetime

def readSensor():

    # Takes a reading from a temperature sensor and store it to temp_measurement

    dateTimeObj = datetime.now()
    timestampStr = dateTimeObj.strftime('%Y-%m-%dT%H:%M:%SZ')

    measurement = {'temperature':str(temp_measurement),'time':timestampStr}
    return measurement

def main():

    print("Cloudflare API Shield [IoT device demonstration]")

    temperature = readSensor()
    payload = json.dumps(temperature)

    url = 'https://shield.upinatoms.com/temps'
    json_headers = {'Content-Type': 'application/json'}
    cert_file = ('/etc/ssl/certs/sensor.pem', '/etc/ssl/private/sensor-key.pem')

    r = requests.post(url, headers = json_headers, data = payload, cert = cert_file)

    print("Request body: ", r.request.body)
    print("Response status code: %d" % r.status_code)

When the script attempts to connect to https://shield.upinatoms.com/temps, Cloudflare requests that a client certificate is sent and the script sends the contents of /etc/ssl/certs/sensor.pem. Then, as required to complete the SSL/TLS handshake, the script demonstrates it has possession of /etc/ssl/private/sensor-key.pem.

Without the client certificate, the Cloudflare rejects the request:

Cloudflare API Shield [IoT device demonstration]
Request body:  {"temperature": "36.5", "time": "2020-09-28T15:52:19Z"}
Response status code: 403

When the IoT device presents a valid client certificate, the POST request succeeds and the temperature reading is recorded:

Cloudflare API Shield [IoT device demonstration]
Request body:  {"temperature": "36.5", "time": "2020-09-28T15:56:45Z"}
Response status code: 201

5. Enable mTLS

After creating Cloudflare-issued certificates, the next step is to enable mTLS for the hosts you want to protect with API Shield.


6. Configure API Shield to require client certificates

To configure API Shield to require client certificates, create a mTLS rule.

Create a client certificate

import { Details, DashButton, GlossaryTooltip } from "~/components";

Use Cloudflare's public key infrastructure (PKI) to create client certificates issued from a Cloudflare-managed CA. You can then complete your mTLS configuration, as explained in How mTLS works.

:::note[Cloudflare-issued or BYOCA] The following process only refers to certificates issued from the Cloudflare-managed CA. To bring your own CA, refer to BYOCA instead. Only available to Enterprise accounts. :::

Quota and limits

By default, each zone allows up to 100 active client certificates issued by the Cloudflare-managed CA. Only active certificates count toward this limit — revoking a certificate frees its slot immediately.

Plan Default limit Increase available
Free, Pro, Business 100 per zone No
Enterprise (with API Shield) 100,000 per zone Yes, via account team

If you reach the limit, the API returns error 1445 with the message Hit maximum certificate allocation: 100 certificates per zone are allowed. To request an increase, contact your account team. Increases require an Enterprise plan with API Shield.

:::note[High-churn workloads]

If your use case involves short-lived or frequently rotated certificates — for example, one certificate per ephemeral device or session — the 100-certificate default can fill up quickly.

Revoke certificates immediately when a device or session ends — revoking frees the quota slot right away. If you need to issue a large volume of certificates, use BYOCA instead. With BYOCA, Cloudflare stores only your CA certificate, not individual issued certificates, so there is no per-certificate inventory limit.

:::

To create a client certificate on the Cloudflare dashboard:

  1. Go to the Client Certificates page.

  2. Select Add Certificate. The Cloudflare-managed CA is the default Certificate Authority.

  3. Fill in the required fields. You can choose one of the following options:

  1. Select a value for Certificate Validity, and choose Continue.

  2. Make sure to copy the certificate and private key as they will no longer be displayed after creation.

  3. (Optional) Specify hostnames where you wish to enable mTLS.

    When associating hostnames via this form, they should be in fully qualified domain name (FQDN) format and correspond to a hostname that exists in the zone you are in. For example, if you are in zone example.com, you can specify host.example.com but not host.example.net.

  4. Select Save to confirm.

Next steps

After creating the client certificate, make sure it is installed on the client devices and enable mTLS for each hostname that should require a certificate from clients.

Refer to our mTLS at Cloudflare learning path for further context.

Enable mTLS

import { Render, DashButton } from "~/components";

You can enable mutual Transport Layer Security (mTLS) for any hostname. For more information, refer to the Client certificates overview.

:::note[Cloudflare-issued or BYOCA] The following process only refers to certificates issued from the Cloudflare-managed CA. For hostnames that should be validated using your own CA, refer to the BYOCA documentation. :::

To enable mTLS for a host from the Cloudflare dashboard:

  1. In the Cloudflare dashboard, go to the Client Certificates page.

  2. On the Hosts section of the Client Certificates card, select Edit.

  3. Enter the name of a host in your current domain. :::note The domain (example.com) is automatically appended for you. This means that, if you want to enable mTLS for abc.example.com, you only need to type abc. :::

  4. Select Save to confirm.

CAs in use

As explained in the Client certificates overview, Cloudflare validates client certificates against CAs set at account level. This means that these certificates can be used for validation across multiple zones/domains (example.com), as long as the zones are under the same Cloudflare account and you have enabled mTLS for the host.

:::note[Bring your own CA] If you need to use your own CA (instead of the Cloudflare-managed CA), refer to BYOCA. This option is available on Enterprise accounts. :::

Next steps

After enabling mTLS for your host, you can:

Forward certificate to server

import { Render } from "~/components";

Client certificates (mTLS)

import { GlossaryDefinition, Render, DirectoryListing } from "~/components";

Standard TLS verifies the server's identity to the client. Mutual TLS (mTLS) adds a second check: the server also verifies the client's identity using a client certificate. This allows you to restrict access to devices or services that present a valid certificate.

Use Cloudflare's public key infrastructure (PKI) to create client certificates, or bring your own CA (BYOCA).

:::note[mTLS at Cloudflare] This documentation is focused on the SSL/TLS product. For a broader overview, refer to the mTLS at Cloudflare learning path. :::


How it works

When a hostname has mTLS enabled, Cloudflare requires connecting clients to present a valid certificate. Client certificates are installed on the devices or services that should be granted access.

Cloudflare validates client certificates against CAs set at the account level. Because validation is account-level, the same certificates work across multiple domains under your account, as long as mTLS is enabled for each hostname (for example, host.example.com, name.example.net, secure.anotherdomain.test).

The account-level CAs can be:

Cloudflare then stores the validation result in a field called cf.tls_client_auth.cert_verified:


Limits

Cloudflare-managed CA

Each zone allows up to 100 active client certificates by default. Only active certificates count toward this quota. Revoking a certificate frees its slot immediately.

Increasing the quota requires an Enterprise account with API Shield. After the entitlement is applied, the default increases to 100,000 per zone. Contact your account team to request an increase.

BYOCA

Each Enterprise account can upload up to five CA certificates. This quota is shared across API Shield, Workers mTLS, and Cloudflare Gateway. It does not apply to CAs uploaded through Cloudflare Access, which uses a separate quota.

Contact your account team to request an increase to the BYOCA CA quota.

:::note[Choosing between managed CA and BYOCA]

Use the Cloudflare-managed CA if you have a small, stable set of clients that authenticate infrequently.

Use BYOCA if you issue certificates at high volume or high churn, already operate an internal CA, or want to issue certificates without calling the Cloudflare API for each one.

:::


Use cases

mTLS supports several implementation patterns depending on what you are protecting. For a broader overview, refer to the mTLS learning path.

Apart from the mTLS Workers binding, any of the above implementations can use your own CA instead of the Cloudflare-managed one. Refer to Bring your own CA.

mTLS and Workers

Use the mTLS Workers binding when you need your worker to present a client certificate to an external service. To authenticate requests from a client to your worker instead, refer to the regular mTLS for application security implementation.

flowchart LR
        accTitle: mTLS from client to worker versus mTLS from worker to external service
        accDescr: Diagram showing two different implementations that can be considered for mTLS with Cloudflare Workers.
        A[Client] <--App security mTLS--> B((Cloudflare))<--mTLS worker binding--> C[(External service)]

Further resources

Label client certificates

After creating client certificates at Cloudflare, it may be hard to differentiate the generated certificates.

Root Cause

The option to generate private key and CSR with Cloudflare is meant for simpler cases and the certificates will be generated with just "CN=Cloudflare, C=US".

Solution

If you need to differentiate client certificates for your clients on a per-organization basis, you can generate your own private key and CSR. When you generate the private key and CSR, you can then enter information that will be incorporated into your certificate request.

For example, if you run the following command (with OpenSSL installed):

openssl req -new -newkey rsa:2048 -nodes -keyout client1.key -out client1.csr

You can then specify:

Country Name (2 letter code) []:
State or Province Name (full name) []:
Locality Name (eg, city) []:
Organization Name (eg, company) []:
Organizational Unit Name (eg, section) []:
Common Name (eg, fully qualified host name) []:
Email Address []:

Usually, adding Country Name and Organization Name is enough, but you can provide as much information as you need or want.

The additional information will be included in the Certificate Subject, allowing you to easily identify which certificate belongs to which client. This can also make it easier to revoke a specific certificate when needed.

The following image displays an example of how a certificate with Country Name, Organization Name, and Organizational Unit Name will look like on the Cloudflare dashboard:

Revoke a client certificate

import { DashButton } from "~/components";

You can revoke a client certificate you previously generated with the default Cloudflare-managed CA.

It is not possible to permanently delete client certificates generated with the default Cloudflare-managed CA. Once revoked, these client certificates will still be listed on the Client Certificates page, and can be restored at any time.

Steps

  1. In the Cloudflare dashboard, go to the Client Certificates page.

  2. Select the certificate you want to revoke.

  3. Select Revoke and confirm the operation.

:::note[Effect on quota]

Revoking a certificate immediately removes it from your active certificate count. Only active certificates count toward the per-zone limit. Revoked certificates remain listed but do not consume quota.

If you manage short-lived or device-bound certificates, revoke them as soon as they are no longer needed. Revoking promptly frees the quota slot without waiting for the certificate to expire.

:::

:::caution[Important]

After revoking a certificate, you must update any mTLS rules that check for the presence of a client certificate so that they block all requests that include a revoked certificate.

For more information, refer to Check for revoked certificates.

:::

Troubleshooting

import { DashButton, Render, Steps, TypeScriptExample } from "~/components";

If your query returns an error even after configuring and embedding a client SSL certificate, check the following settings.

:::note Before troubleshooting, disable VPNs and proxies. These can interfere with the mTLS handshake. :::


Check SSL/TLS handshake

On your terminal, use the following command to check whether an SSL/TLS connection can be established successfully between the client and the API endpoint.

curl --verbose --cert /path/to/certificate.pem --key /path/to/key.pem https://your-api-endpoint.com

If the SSL/TLS handshake cannot be completed, check whether the certificate and the private key are correct. If the handshake completes but requests are still blocked, confirm that Cloudflare is verifying the client certificate.


Check mTLS hosts

Check whether mTLS has been enabled for the correct host. The host should match the API endpoint that you want to protect.


Review mTLS rules

To review mTLS rules, consider the steps below. For further guidance refer to Custom rules.

  1. In the Cloudflare dashboard, go to the Security rules page.

  2. On a specific rule, select Edit.

  3. On that rule, check whether:

    • The Expression Preview is correct.

    • The hostname, if defined, matches your API endpoint. For example, for the API endpoint api.trackers.ninja/time, the rule should look like:

      (http.host in {"api.trackers.ninja"} and not cf.tls_client_auth.cert_verified)
      
  4. To edit the rule, either use the user interface or select Edit expression.


Advanced debugging

You can use Cloudflare Workers to debug client certificate validation failures.

:::caution Do not turn on global_fetch_strictly_public for this Worker. When turned on, fetch(request) can invoke the Worker again instead of reaching the origin. :::

  1. Create a Worker that logs incoming request cf properties and forwards each request to your origin:

    export default {
      async fetch(request): Promise<Response> {
        console.info({ message: JSON.stringify(request.cf, null, 2) });
        return fetch(request);
      },
    } satisfies ExportedHandler;
    
  2. Associate the Worker with the hostname where mTLS is enabled using a Worker route.

  3. Make requests to the hostname and/or path configured, with and without sending the mTLS client certificate.

  4. In the Observability dashboard, compare the logged tlsClientAuth values with the expected values.


Certificate quota reached

Cloudflare-managed CA

Cloudflare-managed client certificates count against a per-zone quota. To free up a slot, revoke certificates you no longer need. Revoking a certificate immediately releases the slot.

To list and revoke certificates, refer to the client certificates API.

Bring your own CA (BYOCA)

Each Enterprise account can upload up to five CA certificates for BYOCA. This quota is shared across API Shield, Workers mTLS, and Cloudflare Gateway.

If you exceed this limit, the API returns:

{
  "code": 1489,
  "message": "Hit maximum CA cert allocation."
}

To free a slot, you must first remove all hostname associations from the CA before deleting it. To increase your quota, contact your account team.

:::note CAs uploaded through Cloudflare Access use a separate quota. Error 12130 ("maximum number of certificates has been reached") in Access refers to the Access-specific certificate limit, not the BYOCA quota described in Bring your own CA (BYOCA). :::


BYOCA certificate upload errors

When uploading a CA certificate for Bring your own CA (BYOCA), the certificate must meet the following requirements:

Upload the CA certificate, not a leaf certificate

The certificate you upload must be a CA certificate — that is, it must have Basic Constraints: CA=TRUE in its extensions. Upload the CA certificates in your client certificates' chain, not a client certificate itself.

A common cause of upload failure is uploading a leaf (client) certificate instead of the CA certificate. If your certificate chain is Root CA → Intermediate CA → Client certificate, upload the full CA chain in a single PEM file, with the Intermediate CA followed by the Root CA.

If you upload only the Intermediate CA, mTLS validation fails for every request, even when the hostname is associated with the CA. In your HTTP request logs, ClientMTLSAuthCertFingerprint matches the expected client certificate, but ClientMTLSAuthStatus is unknown.

To confirm that a certificate is a CA certificate, run the following command on each certificate in the chain:

openssl x509 -in certificate.pem -noout -text | grep -A1 "Basic Constraints"

The output should include CA:TRUE. If it shows CA:FALSE or the field is absent, the certificate is not a CA certificate and cannot be uploaded.

Unsupported signature algorithm

The CA certificate must use one of the following signature algorithms:

If the CA certificate uses a different algorithm, re-issue it using a supported one.

Malformed PEM content

The certificates field in the upload request must contain valid, properly delimited PEM content. Ensure the certificate starts with -----BEGIN CERTIFICATE----- and ends with -----END CERTIFICATE-----. Do not include private keys or certificate signing requests in this field.

Backup certificates

If Cloudflare is providing authoritative DNS for your domain, Cloudflare will issue a backup Universal SSL certificate for every standard Universal certificate issued.

Backup certificates are wrapped with a different private key and issued from a different Certificate Authority — either Google Trust Services, Let's Encrypt, Sectigo, or SSL.com — than your domain's primary Universal SSL certificate.

These backup certificates are not normally deployed, but they will be deployed automatically by Cloudflare in the event of a certificate revocation or key compromise.

For additional details, refer to the introductory blog post.

Availability

Free Pro Business Enterprise
Availability Yes Yes Yes Yes
Can opt out? No No No Yes

Opt out

Enterprise customers can request to opt out of backup certificates by opening a support case. Opting out removes the backup-certificate redundancy for your domain.

Troubleshooting

Backup certificate deleted after turning Universal SSL back on

After you turn off and quickly turn Universal SSL back on, your domain may end up without a backup certificate.

When Universal SSL is toggled off and on in quick succession, certificate processing jobs are not guaranteed to run in the order they were submitted. This race condition can cause a newly issued backup certificate to be deleted before it becomes active.

To recover your backup certificate:

  1. Turn Universal SSL off again.
  2. Wait several minutes.
  3. Turn Universal SSL back on, then allow time for Cloudflare to issue a new backup certificate.

If you need uninterrupted certificate coverage, consider ordering an Advanced Certificate Manager certificate before toggling Universal SSL.

For more troubleshooting help, refer to Troubleshooting SSL errors.

Add CAA records

import { Render, TabItem, Tabs, DashButton } from "~/components";


For additional security, set up Certificate Transparency Monitoring as well.

:::note[Note]

For more technical details about CAA records, refer to the introductory blog post.

:::

Who should create CAA records?

You should create CAA records in Cloudflare if each of the following is true:

CAA records added by Cloudflare

Create CAA records

Create a CAA record for each Certificate Authority (CA) that you plan to use for your domain.

To add a CAA record in the dashboard,

  1. In the Cloudflare dashboard, go to the DNS Records page.

  2. Select Add record.

  3. For Type, select CAA.

  4. For Name, type your domain.

  5. Choose a Tag, which specifies the behavior associated with the record.

  6. For CA domain name, enter the CA name.

  7. Select Save.

  8. Repeat for each CA associated with your domain.

To create a CAA record via the API, use this POST endpoint.

Once you have finished creating all the records, you can review them in the list of records appearing under the DNS Records panel.

Certificate authorities and required CAA values

If you have CAA records on your domain, they must permit the certificate authority (CA) that Cloudflare uses. For the required CAA values for each CA Cloudflare may use, refer to Certificate authorities.

CNAME chain CAA records

CAA records on a CNAME target also apply. If your hostname CNAMEs to a domain whose zone has restrictive CAA records, those records take precedence — even if your own domain has no CAA records.

Check CAA at all levels of your CNAME chain:

dig yourdomain.com CAA +short
dig cname-target.com CAA +short

ECH Protocol

import { DashButton } from "~/components";

ECH stands for Encrypted Client Hello. It is a protocol extension in the context of Transport Layer Security (TLS). ECH encrypts part of the handshake and masks the Server Name Indication (SNI) that is used to negotiate a TLS session. This means that whenever a user visits a website on Cloudflare that has ECH enabled, intermediaries will be able to see that you are visiting a website on Cloudflare, but they will not be able to determine which one.

What ECH does

ECH limits access to information that a particular user is visiting your website, ensuring that it is not unnecessarily shared with intermediaries, like Internet Service Providers (ISP). With ECH, specific details regarding their visit no longer leak to network intermediaries when the user accesses your website.

How ECH works

In a typical TLS handshake, the client sends a ClientHello message to the server to initiate the TLS session. This message contains important information, including the list of supported cryptographic algorithms, TLS version, and the requested server name (the domain name of the website the client wants to connect to). The server name is indicated through Server Name Indication (SNI).

With ECH, the ClientHello message part is split into two separate messages: an inner part and an outer part. The outer part contains the non-sensitive information such as which ciphers to use and the TLS version and an "outer ClientHello". The inner part is encrypted and contains an "inner ClientHello".

The outer ClientHello contains a common name (SNI) that represents that a user is trying to visit an encrypted website on Cloudflare. We chose cloudflare-ech.com as the SNI that all websites will share on Cloudflare. Because Cloudflare controls that domain, we have the appropriate certificates to be able to negotiate a TLS handshake for that server name.

The inner ClientHello contains the actual server name that the user is trying to visit. This is encrypted using a public key and can only be read by Cloudflare. Once the handshake completes, the web page is loaded as normal, just like any other website loaded over TLS.

In practice, this means that any intermediary that is looking at your traffic will simply see normal TLS handshakes with one caveat: any traffic to an ECH-enabled server name on Cloudflare will look the same. Every TLS handshake will appear identical in that it looks like it is trying to load a website for cloudflare-ech.com, as opposed to the actual website.

In the example below, a user is visiting example.com. Without ECH, any intermediate networks will be able to detect the website being accessed by the user. With ECH, the visible information will be limited to cloudflare-ech.com instead.


flowchart LR
accTitle: What intermediaries see with and without ECH
accDescr: This diagram describes what intermediaries see with and without ECH.
A(User visits <code>example.com</code>)
    A -- With ECH --> C(intermediaries see <code>cloudflare-ech.com</code>)-->B(Cloudflare)
    A -- Without ECH  --> D(intermediaries see <code>example.com</code>)-->B(Cloudflare)

For more details about ECH protocol technology, refer to our introductory blog.

Enable ECH

ECH is enabled by default on Free zones. Other plans can turn it on or off following the steps below.

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. For Encrypted ClientHello (ECH), change the setting to Enabled.

Enterprise network applicability

Some enterprise or regional networks may need to audit or apply filtering policies to traffic that traverses their network. These policies are expressed in terms of domain names, not IP addresses. Consequently, they are best applied at the local DNS resolver in response to the A and AAAA queries for the individual domain names.

However, for settings wherein DNS-based filtering is not applicable, there are two ways in which networks can disable ECH to allow existing filtering mechanisms to continue working as expected.

The most reliable way is via the local or recursive DNS resolver itself, by dropping ECH configurations from HTTPS resource records returned to clients, or, preferably, by returning a “no error no answer” or NXDOMAIN response to HTTPS queries. This prevents clients from obtaining the necessary information to use ECH. Note that modifying HTTPS resource records may cause failures for clients that perform DNSSEC validation, so dropping HTTPS responses may be the preferred approach. This will prevent browsers, such as Chrome from using ECH.

The second way to disable ECH is via a network canary domain. In particular, your network’s DNS resolver can return a “no error no answer” or an NXDOMAIN response to queries made to the use-application-dns.net canary domain. This will prevent browsers, such as Firefox from using ECH. For more information, see Firefox's frequently asked questions page for Encrypted Client Hello.

Enforce HTTPS connections

Even with an active SSL/TLS certificate, visitors can still access resources over unsecured HTTP connections.

It is best to redirect this traffic over HTTPS, as well as ensure other resources (such as images) are also loaded over HTTPS.

Prerequisites

Before trying to enforce HTTPS connections, make sure that your application has an active edge certificate. Otherwise, visitors will not be able to access your application at all.

Also, make sure that your SSL encryption mode is not set to Off. Otherwise, Cloudflare will redirect all visitor connections automatically to HTTP.

1. Evaluate existing redirects

To make sure that your visitors do not get stuck in a redirect loop, evaluate existing redirects at your origin server and within the Cloudflare dashboard.

You should generally avoid redirects at your origin server. Not only are you likely to forget about them, but they also reduce application performance. It is much faster for Cloudflare to redirect requests before they ever reach your origin.

Make sure that your redirects within Cloudflare are not forwarding traffic to URLs starting with http.

2. Rewrite HTTP URLs

If your application contains links or references to HTTP URLs, your visitors might see mixed content errors when accessing an HTTPS page.

To avoid these issues, enable Automatic HTTPS Rewrites and pay attention to which HTTP requests are still reaching your origin server.

3. Redirect traffic to HTTPS

If your entire application can support HTTPS traffic, enable Always Use HTTPS.

If only some parts of your application can support HTTPS traffic, do not enable Always Use HTTPS and use a single redirect to selectively perform the redirect to HTTPS. Refer to Redirect admin area requests to HTTPS for an example.

Edge certificates

import { GlossaryTooltip } from "~/components";

Edge certificates are the SSL/TLS certificates that Cloudflare presents to visitors connecting to your domain. These certificates secure the encrypted connection between your visitors and Cloudflare.

Use the guidance below to choose the right certificate type for your use case. If you are not familiar with SSL/TLS certificates, refer to Concepts.

:::note Occasionally, the Cloudflare dashboard displays a wildcard certificate with only the apex hostname listed (and does not include the wildcard symbol *).

This behavior occurs when all of the following conditions are true:

Use cases

Simplify issuance and renewal

Managing certificate issuance, renewal, and expiration tracking can be time-consuming. Cloudflare can handle this for you:

Meet cipher suites requirements

A cipher suite is a set of encryption algorithms that a visitor's browser and the server negotiate when establishing a secure connection. Some compliance standards (for example, PCI DSS) require specific cipher suites or prohibit older ones.

With cipher suites customization, you can set different cipher suites per hostname. For example, you could allow broader compatibility on www.example.com for legacy devices while enforcing stricter compliance standards on shop.example.com.

Custom cipher suites apply to any edge certificate serving that hostname. To use this feature, you must purchase the Advanced Certificate Manager add-on. Refer to Customize cipher suites for setup instructions.

Automate domain control validation (DCV)

Before a certificate authority (CA) issues a certificate, it must verify you control the domain. This process is called domain control validation (DCV).

If Cloudflare runs your authoritative DNS (full setup), DCV happens automatically. If you manage DNS with another provider (partial setup), you may need to complete DCV manually each time a certificate is issued or renewed.

To automate DCV for partial setups, use advanced certificates with delegated DCV.

Staging environment

import { DashButton } from "~/components"

Use your certificate staging environment to test new custom (modern) certificates before pushing them to your production environment. This process helps you solve potential certificate problems before there's an incident, such as when:

Availability

Free Pro Business Enterprise
Availability No No No Yes (open beta)

Use your staging environment

1. Upload certificate

To upload custom (modern) certificates to your staging environment:

  1. In the Cloudflare dashboard, go to the Staging Certificates page.

  2. Select Upload Custom Staging Certificate.

  3. Upload your custom (modern) certificate (detailed instructions).

  4. Your certificate will appear in the dashboard with a status of Staging Deployment. If you refresh the page, its status should go to Staging Active.

2. Test certificate

Test your custom (modern) certificate by sending curl requests to the IP addresses listed on the Staging Certificates page:

curl --resolve <HOSTNAME>:<PORT>:<STAGING_IP> https://<HOSTNAME> -iv

You should confirm whether:

3. Push certificate to production

Assuming there are no issues, push your custom (modern) certificate to your production environment:

  1. In the Cloudflare dashboard, go to the Staging Certificates page.

  2. Select a custom certificate.

  3. Select Push to Production.

If there were issues with your certificate, you can keep it in your staging environment or select Deactivate on the certificate itself.

4. (Optional) Push certificate back to staging

If you roll out a custom (modern) certificate to production and encounter issues, you can deactivate that certificate to delete the certificate from the edge and then push the certificate back to your staging environment for additional testing:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. Select a custom certificate.

  3. Select Deactivate.

  4. Select Push to Staging.


Limitations

Access

Currently, staging environments are only available to Enterprise customers participating in an open beta. To get access to the beta, contact your Account team.

Functionality

At the moment, staging environments have limited functionality:

Always Use HTTPS

import { Render } from "~/components";

Always Use HTTPS redirects all your visitor requests from http to https, for all subdomains and hosts in your application.

:::note

This process does not impact certificate validation. If you use HTTP DCV, you can still enable Always Use HTTPS. :::

Cloudflare recommends not performing redirects at your origin web server, as this can cause redirect loop errors.

Availability

Free Pro Business Enterprise
Availability Yes Yes Yes Yes

Encrypt all visitor traffic

To redirect traffic for all subdomains and hosts in your application, you can enable Always Use HTTPS.

:::note

If only some parts of your application can support HTTPS traffic, do not enable Always Use HTTPS and use a single redirect to selectively perform the redirect to HTTPS. Refer to Redirect admin area requests to HTTPS for an example. :::

Limitations

Forcing HTTPS does not resolve issues with mixed content, as browsers check the protocol of included resources before making a request. You will need to use only relative links or HTTPS links on pages that you force to HTTPS. Cloudflare can automatically resolve some mixed-content links using our Automatic HTTPS Rewrites functionality.

Automatic HTTPS Rewrites

import { Render, TabItem, Tabs, DashButton } from "~/components";

Automatic HTTPS Rewrites prevents end users from seeing "mixed content" errors by rewriting URLs from http to https for resources or links on your web site that can be served with HTTPS.

Availability

Free Pro Business Enterprise
Availability Yes Yes Yes Yes

Additional details

If your site contains links or references to HTTP URLs that are also available securely via HTTPS, Automatic HTTPS Rewrites can help. If you connect to your site over HTTPS and the lock icon is not present, or has a yellow warning triangle on it, your site may contain references to HTTP assets (“mixed content”).

Mixed content is often due to factors not under the website owner’s control such as embedded third-party content or complex content management systems. By rewriting URLs from “http” to “https”, Automatic HTTPS Rewrites simplifies the task of making your entire website available over HTTPS, helping to eliminate mixed content errors and ensuring that all data loaded by your website is protected from eavesdropping and tampering.

:::note

For security reasons, this feature will run on URLs pointing to localhost if the URL is fetching an active resource (script, iframe, link, object, etc.).

:::

Enable Automatic HTTPS Rewrites

To enable Automatic HTTPS Rewrites in the dashboard:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. For Automatic HTTPS Rewrites, switch the toggle to On.

To enable or disable Automatic HTTPS Rewrites with the API, send a PATCH request with automatic_https_rewrites as the setting name in the URI path, and the value parameter set to your desired setting ("on" or "off").

Limitations

Before a rewrite is applied, Cloudflare checks the HTTP resources to ensure they are accessible via HTTPS. If they are not available over HTTPS, Cloudflare cannot rewrite the URL.

Some resources are loaded by JavaScript or CSS via HTTP when the site is loaded in a browser. You will see mixed content warnings in those situations. To determine which URLs do not have HTTPS support, Cloudflare uses data from EFF’s HTTPS Everywhere and Chrome’s HSTS preload list. If your zone is not on one of these lists, only active content will be rewritten. Passive content (such as images) will not be rewritten and will still cause mixed content errors.

If a third-party domain supports HTTPS and is not rewritten automatically, you can manually change those links to relative links or HTTPS links. Alternatively, you can ask the third-party domain owner to submit their site for inclusion in the HTTPS Everywhere rulesets, which accept pull requests on GitHub. For more information on how to fix mixed content errors, refer to Troubleshooting mixed content errors.

Certificate Signing Requests (CSRs)

import { Render, DashButton } from "~/components";

Availability

Free Pro Business Enterprise
Availability No No No Included with Advanced Certificate Manager

Types of CSRs

You can create two types of CSRs:

Create and use a CSR

To create a CSR:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. On Certificate Signing Request (CSR), select Generate.

  3. Choose a Scope (only certain customers can choose Account).

  4. Enter relevant information on the form and select Create.

To use a CSR:

  1. On the Edge Certificates page, select the CSR record you just created under Certificate Signing Request (CSR).

  2. Copy (or select Click to copy) the value for Certificate Signing Request.

  3. Obtain a certificate from the Certificate Authority (CA) of your choice using your CSR.

  4. When you upload the custom certificate to Cloudflare, select an Encoding mode of Certificate Signing Request (CSR) and enter the associated value.

    :::note You will not see the option to adjust your Encoding Mode until after you have created a CSR associated with the specific zone or your account. :::

Renew a certificate

When you renew a custom certificate, you need to reuse a previously generated CSR.

Note that it is not possible to use a different CSR with the same certificate. In this case, you must upload the certificate as a new certificate, selecting the new CSR.

Certificate Transparency Monitoring

import { GlossaryTooltip } from "~/components";

Certificate Transparency (CT) Monitoring is an opt-in feature that lets you double-check any SSL/TLS certificates issued for your domain.

CT Monitoring alerts are triggered whenever a certificate that covers your monitored domain is issued by a Certificate Authority (CA) and added to a public CT log. Alerts for certificates Cloudflare issues on your behalf, including backup certificates, are automatically filtered out. For more information, refer to Certificate Transparency Monitoring filtering behavior, or to the introductory blog post to learn more about how CT Monitoring works.

:::caution[Aspects to consider]

:::


Opt in and out

Alerts are turned off by default. If you want to receive alerts, go to the Edge Certificates page and turn on Certificate Transparency Monitoring, then select Add Email.

To stop receiving alerts, turn off Certificate Transparency Monitoring or remove your email from the feature card.


Emails to be concerned about

Cloudflare filters out the certificates it issues for you, so every alert you get is worth a quick look.

Most alerts are routine. Open the email and check three things:

  1. Your domain. Does it match what you own?
  2. The issuer. Did you or your organization request this certificate, or was it requested by a service you use? The issuer is listed as the Certificate Authority in the email.
  3. The DNS names and validity dates. Do they look reasonable?

If you can confirm that your organization or a service you use requested the certificate, no action is required. Otherwise, investigate the issuance with your security team or certificate provider. You can review certificates configured on Cloudflare from the Edge Certificates page in the dashboard. For external certificates, review the CT log entry or use Certificate Search.

Take action if:


How to take action

Option 1: Contact certificate authorities

Only Certificate Authorities can revoke malicious certificates. If you believe an illegitimate certificate was issued for your domain, contact the Certificate Authority listed as the Issuer in the email.

Option 2: Contact domain registrars

Domain registrars may be able to suspend potentially malicious domains. If, for example, you notice that a malicious domain was registered through GoDaddy, contact GoDaddy’s support team to see if they can help you. Do the same for other registrars.

Option 3: Improvise

There are other ways to combat malicious certificates. You can warn your visitors with an on-site notification or ask browser makers (Google for Chrome, etc.) to block these domains.

If someone is attempting to impersonate you online, you should absolutely take action. This is usually difficult to recognize, so exercise caution. Remember: the vast majority of certificates are not malicious. Only take action if you believe something is wrong.


HTTP Public Key Pinning

Certificate Transparency Monitoring addresses the same problems as HTTP Public Key Pinning (HPKP), but with fewer technical issues.

Cloudflare does not offer or support HPKP and advises against using it with Universal SSL.

HTTP Strict Transport Security (HSTS)

import { TabItem, Tabs, DashButton } from "~/components";

HSTS protects HTTPS web servers from downgrade attacks. These attacks redirect web browsers from an HTTPS web server to an attacker-controlled server, allowing bad actors to compromise user data and cookies.

HSTS adds an HTTP header that directs compliant web browsers to:

Before enabling HSTS, review the requirements.

:::note

For more background information on HSTS, see the introductory blog post.

:::

Availability

Free Pro Business Enterprise
Availability Yes Yes Yes Yes

Requirements

In order for HSTS to work as expected, you need to:

Once you enabled HSTS, avoid the following actions to ensure visitors can still access your site:

:::caution

If you remove HTTPS before disabling HSTS or before waiting for the duration of the original Max Age Header specified in your Cloudflare HSTS configuration, your website becomes inaccessible to visitors for the duration of the Max Age Header or until you enable HTTPS.

:::

Enable HSTS

To enable HSTS using the dashboard:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. For HTTP Strict Transport Security (HSTS), select Enable HSTS.

  3. Read the dialog and select I understand.

  4. Select Next.

  5. Configure the HSTS settings.

  6. Select Save.

To enable HSTS with the API, send a PATCH request with security_header as the setting name in the URI path, and specify the value object that includes your HSTS settings.

:::note

To enable HSTS on a specific subdomain only, configure a subdomain setup. Alternatively, you can add the appropriate HSTS header at the origin, or use a response header transform rule.

:::

Disable HSTS

To disable HSTS on your website:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. For HTTP Strict Transport Security (HSTS), select Enable HSTS.

  3. Set the Max Age Header to 0 (Disable).

  4. If you previously enabled the No-Sniff header and want to remove it, set it to Off.

  5. Select Save.

Configuration settings

Name Required Description Options
Enable HSTS (Strict-Transport-Security) Yes Serves HSTS headers to browsers for all HTTPS requests. HTTP (non-secure) requests will not contain the header. Off / On
Max Age Header (max-age) Yes Specifies duration for a browser HSTS policy and requires HTTPS on your website. Disable, or a range from 1 to 12 months
Apply HSTS policy to subdomains (includeSubDomains) No Applies the HSTS policy from a parent domain to subdomains. Subdomains are inaccessible if they do not support HTTPS. Off / On
Preload No Permits browsers to automatically preload HSTS configuration. Prevents an attacker from downgrading a first request from HTTPS to HTTP. Preload can make a website without HTTPS completely inaccessible. Off / On
No-Sniff Header No Sends the X-Content-Type-Options: nosniff header to prevent Internet Explorer and Chrome from automatically detecting a content type other than those explicitly specified by the Content-Type header. Off / On

:::note

Once HSTS Preload is configured, submit requests for addition to each browser’s preload list. Chrome, Firefox/Mozilla, and Safari use the Chrome preload list. A minimum Max Age Header of 12 months is required for inclusion in HSTS preload lists.

:::

:::note[Testing with external scanners] HSTS settings are applied per hostname. When using external scanners such as SSL Labs, ensure you are testing the exact hostname where HSTS is configured. Scanning an IP address or a different hostname will not show the HSTS header. :::

Additional options

import { DirectoryListing } from "~/components"

Once you set up SSL/TLS on your application, you can adjust the following settings on the Edge Certificates page:

Minimum TLS Version

import { TabItem, Tabs, APIRequest, Render, DashButton } from "~/components";

Minimum TLS Version only allows HTTPS connections from visitors that support the selected TLS protocol version or newer.

For example, if TLS 1.1 is selected, visitors attempting to connect using TLS 1.0 will be rejected. Visitors attempting to connect using TLS 1.1, 1.2, or 1.3 (if enabled) will be allowed to connect.

:::note

If you are looking to restrict cipher suites, refer to Customize cipher suites. For guidance on which TLS version to use, refer to TLS protocols.

:::

Availability

Free Pro Business Enterprise
Availability Yes Yes Yes Yes
Per-hostname Included with Advanced Certificate Manager Included with Advanced Certificate Manager Included with Advanced Certificate Manager Included with Advanced Certificate Manager

It is not possible to configure minimum TLS version for Cloudflare Pages hostnames.

How to disable TLS 1.0

You can disable TLS 1.0 by choosing a higher minimum TLS version.

All users can apply this configuration to all hostnames in their zones following the steps under zone-level.

If you have an Advanced Certificate Manager subscription, you also have the option to disable TLS 1.0 (or other versions) with a per-hostname setup.

Setup

:::caution The Minimum TLS version that you set up following these steps does not apply to R2 custom domains. To control the TLS version for R2 custom domains, refer to the custom domains documentation. :::

Zone-level

To manage the TLS version applied to your whole zone when proxied through Cloudflare:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. For Minimum TLS Version, select an option.

Use the Edit zone setting endpoint with min_tls_version as the setting name in the URI path, and specify your preferred minimum version in the value field.

In the following example, the minimum TLS version for the zone will be set to 1.2. Replace the zone ID and API token placeholders with your information, and adjust the value field with your chosen TLS version.

<APIRequest path="/zones/{zone_id}/settings/{setting_id}" method="PATCH" json={{ "id": "min_tls_version", "value": "1.2", }} parameters={{ setting_id: "min_tls_version" }} />

Per-hostname

Advanced Certificate Manager users also have the option to specify minimum TLS versions per specific hostnames in their Cloudflare zone.

This is currently only available via the API:

Cloudflare uses the hostname priority logic to determine which setting to apply.

In the following example, the minimum TLS version for a specific hostname will be set to 1.2. Replace the zone ID, hostname, and authentication placeholders with your information, and adjust the value field with your chosen TLS version.

<APIRequest path="/zones/{zone_id}/hostnames/settings/{setting_id}/{hostname}" method="PUT" json={{ "value": "1.2" }} parameters={{ setting_id: "min_tls_version" }} />

Cloudflare for SaaS

If you are a SaaS provider looking to configure minimum TLS version for your custom hostnames, refer to the Cloudflare for SaaS TLS management.

Test supported TLS versions

Opportunistic Encryption

import { Render, TabItem, Tabs, DashButton } from "~/components";

Opportunistic Encryption allows browsers to access HTTP URIs over an encrypted TLS channel. It's not a substitute for HTTPS, but provides additional security for otherwise vulnerable requests.

Use HTTPS when both strong encryption and authentication are required. HTTP Opportunistic Encryption provides a means of enabling TLS when needed for other protocols such as HTTP/2. It does not provide the same indications of security as HTTPS (the green lock icon in most browser address bars).

Availability

Free Pro Business Enterprise
Availability Yes Yes Yes Yes

Enable Opportunistic Encryption

You do not need to configure your origin web server to support Opportunistic Encryption. All it requires is updating your settings in the Cloudflare dashboard.

To enable Opportunistic Encryption in the dashboard:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. For Opportunistic Encryption, switch the toggle to On.

To adjust your Opportunistic Encryption settings with the API, send a PATCH request with opportunistic_encryption as the setting name in the URI path, and specify the value parameter with your desired setting ("on" or "off").

TLS 1.3

import { Details, Render, TabItem, Tabs, DashButton } from "~/components";

TLS 1.3 enables the latest version of the TLS protocol (when supported) for improved security and performance.

What is TLS 1.3?

TLS 1.3 is the newest, fastest, and most secure version of the TLS protocol.

By turning on the TLS 1.3 feature, traffic to and from your website will be served over the TLS 1.3 protocol when supported by clients. TLS 1.3 protocol has improved latency over older versions, has several new features, and is currently supported in all updated major browsers.

Availability

Free Pro Business Enterprise
Availability Yes Yes Yes Yes

Enable TLS 1.3

TLS 1.3 can be activated in the Cloudflare dashboard or through the API:

To enable TLS 1.3 in the dashboard:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. For TLS 1.3, switch the toggle to On.

To adjust your TLS 1.3 settings with the API, send a PATCH request with tls_1_3 as the setting name in the URI path, and set the value parameter to your desired setting ("on", "zrt" or "off"). zrt refers to Zero Round Trip Time Resumption (0-RTT).

Troubleshooting

Since TLS 1.3 implementations are relatively new, some failures may occur. If you experience errors, submit a Cloudflare Support ticket with the following information:

Chrome users should submit a net-internals trace to Google. Firefox users should report bugs to Mozilla.

Limitations

Compliance standards

import { Render, Details } from "~/components";

Consider the following recommendations on custom cipher suites for when your organization needs to comply with regulatory standards.

Refer to Customize cipher suites to learn how to specify cipher suites at zone level or per hostname.

:::caution Also enable TLS 1.3 on your zone and, when opting for PCI DSS, make sure to up your Minimum TLS version to 1.2. Refer to Cipher suites and TLS protocols to learn more. :::

PCI DSS

AEAD-AES128-GCM-SHA256[^1], AEAD-AES256-GCM-SHA384[^2], AEAD-CHACHA20-POLY1305-SHA256[^3], ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-RSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-RSA-AES256-GCM-SHA384, ECDHE-ECDSA-CHACHA20-POLY1305, ECDHE-RSA-CHACHA20-POLY1305

</ Details>

FIPS-140-3

Recommended cipher suites for compliance with the Federal Information Processing Standard (140-3). Used to approve cryptographic modules.

AES128-GCM-SHA256, AES128-SHA, AES128-SHA256, AES256-SHA, AES256-SHA256, DES-CBC3-SHA, ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES128-SHA, ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES256-SHA384, ECDHE-RSA-AES128-GCM-SHA256, ECDHE-RSA-AES128-SHA, ECDHE-RSA-AES128-SHA256, ECDHE-RSA-AES256-GCM-SHA384, ECDHE-RSA-AES256-SHA, ECDHE-RSA-AES256-SHA384

</ Details>

[^1]: Same as TLS_AES_128_GCM_SHA256. Refer to TLS 1.3 cipher suites for details.

[^2]: Same as TLS_AES_256_GCM_SHA384. Refer to TLS 1.3 cipher suites for details.

[^3]: Same as TLS_CHACHA20_POLY1305_SHA256. Refer to TLS 1.3 cipher suites for details.

Cipher suites

import { DirectoryListing, Render } from "~/components";


This section covers cipher suites used in connections between visitors and the Cloudflare network. Cipher suites used between Cloudflare and your origin server are configured separately — refer to Origin server > Cipher suites.

Compliance standards such as PCI DSS may require specific cipher suites or prohibit older ones, and security testing tools like Qualys SSL Labs may flag Cloudflare's default configuration.

:::note

Cloudflare maintains a public repository of our SSL/TLS configurations on GitHub, where you can find changes in the commit history.

RC4 cipher suites or SSLv3 are no longer supported. :::

Cipher suites and edge certificates

Cloudflare's default cipher suites (Legacy) balance security and compatibility, which means they include older algorithms that security testing tools may flag.

If the default configuration does not meet your requirements, you can purchase the Advanced Certificate Manager add-on to specify more secure cipher suites.

Cipher suite customization is a hostname-level setting. Once specified, the configuration applies to all edge certificates serving that hostname, regardless of certificate type (universal, advanced, or custom).

Although configured independently, cipher suites interact with other SSL/TLS settings.

Minimum TLS Version

You can specify a minimum TLS version that is required for a client to connect to your website or application.

For example, if TLS 1.1 is selected as the minimum, visitors attempting to connect using TLS 1.0 will be rejected while visitors attempting to connect using TLS 1.1, 1.2, or 1.3 (if enabled) will be allowed.

Certain cipher suites are only available in specific TLS versions. If you restrict cipher suites to a higher security level that excludes older algorithms, you should also adjust your minimum TLS version to match.

Compliance standards may also require you to increase the minimum TLS version accepted in connections to your website or application.

TLS 1.3

Cloudflare may return the following names for TLS 1.3 cipher suites. This is how they map to RFC 8446 names:

Cloudflare RFC 8446
AEAD-AES128-GCM-SHA256 TLS_AES_128_GCM_SHA256
AEAD-AES256-GCM-SHA384 TLS_AES_256_GCM_SHA384
AEAD-CHACHA20-POLY1305-SHA256 TLS_CHACHA20_POLY1305_SHA256

Resources

Limitations

It is not possible to configure cipher suites for Cloudflare Pages hostnames.

Security levels

import { Render, Details } from "~/components";

Refer to the sections below for three different security levels and how Cloudflare recommends that you set them up if you need to restrict the cipher suites used between Cloudflare and clients that access your website or application.

Refer to Customize cipher suites to learn how to specify cipher suites at zone level or per hostname.

:::caution Before opting for compatible or modern, review the related SSL/TLS settings[^4]. :::

Modern

Offers the best security and performance, limiting your range of clients to modern devices and browsers. Supports TLS 1.2-1.3 cipher suites. All suites are forward-secret and support authenticated encryption (AEAD).

AEAD-AES128-GCM-SHA256[^1], AEAD-AES256-GCM-SHA384[^2], AEAD-CHACHA20-POLY1305-SHA256[^3],ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-CHACHA20-POLY1305, ECDHE-RSA-AES128-GCM-SHA256, ECDHE-RSA-CHACHA20-POLY1305, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-RSA-AES256-GCM-SHA384

</ Details>

Compatible

Provides broader compatibility with somewhat weaker security. Supports TLS 1.2-1.3 cipher suites. All suites are forward-secret.

AEAD-AES128-GCM-SHA256[^1], AEAD-AES256-GCM-SHA384[^2], AEAD-CHACHA20-POLY1305-SHA256[^3], ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-CHACHA20-POLY1305, ECDHE-RSA-AES128-GCM-SHA256, ECDHE-RSA-CHACHA20-POLY1305, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-RSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES128-SHA256, ECDHE-RSA-AES128-SHA256, ECDHE-ECDSA-AES256-SHA384, ECDHE-RSA-AES256-SHA384

</ Details>

Legacy (default)

Includes all cipher suites that Cloudflare supports today. Broadest compatibility with the weakest security. Supports TLS 1.0-1.3 cipher suites.

AEAD-AES128-GCM-SHA256[^1], AEAD-AES256-GCM-SHA384[^2], AEAD-CHACHA20-POLY1305-SHA256[^3], ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-CHACHA20-POLY1305, ECDHE-RSA-AES128-GCM-SHA256, ECDHE-RSA-CHACHA20-POLY1305, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-RSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES128-SHA256, ECDHE-RSA-AES128-SHA256, ECDHE-ECDSA-AES256-SHA384, ECDHE-RSA-AES256-SHA384, ECDHE-ECDSA-AES128-SHA, ECDHE-RSA-AES128-SHA, AES128-GCM-SHA256, AES128-SHA256, AES128-SHA, ECDHE-RSA-AES256-SHA, AES256-GCM-SHA384, AES256-SHA256, AES256-SHA, DES-CBC3-SHA

</ Details>

To reset your option to the default, use an empty array.

[^1]: Same as TLS_AES_128_GCM_SHA256. Refer to TLS 1.3 cipher suites for details. [^2]: Same as TLS_AES_256_GCM_SHA384. Refer to TLS 1.3 cipher suites for details. [^3]: Same as TLS_CHACHA20_POLY1305_SHA256. Refer to TLS 1.3 cipher suites for details. [^4]: Although configured independently, cipher suites interact with Minimum TLS version and TLS 1.3.

Supported cipher suites

Cloudflare supports the following cipher suites by default. If needed, you can restrict your website or application to only use specific cipher suites.

Cipher name Minimum protocol Security recommendation Cipher suite IANA name
ECDHE-ECDSA-AES128-GCM-SHA256 TLS 1.2 Modern, Compatible, Legacy [0xc02b] TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
ECDHE-ECDSA-CHACHA20-POLY1305 TLS 1.2 Modern, Compatible, Legacy [0xcca9] TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
ECDHE-RSA-AES128-GCM-SHA256 TLS 1.2 Modern, Compatible, Legacy [0xc02f] TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
ECDHE-RSA-CHACHA20-POLY1305 TLS 1.2 Modern, Compatible, Legacy [0xcca8] TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
ECDHE-ECDSA-AES128-SHA256 TLS 1.2 Compatible, Legacy [0xc023] TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
ECDHE-ECDSA-AES128-SHA TLS 1.0 Legacy [0xc009] TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
ECDHE-RSA-AES128-SHA256 TLS 1.2 Compatible, Legacy [0xc027] TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
ECDHE-RSA-AES128-SHA TLS 1.0 Legacy [0xc013] TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
AES128-GCM-SHA256 TLS 1.2 Legacy [0x9c] TLS_RSA_WITH_AES_128_GCM_SHA256
AES128-SHA256 TLS 1.2 Legacy [0x3c] TLS_RSA_WITH_AES_128_CBC_SHA256
AES128-SHA TLS 1.0 Legacy [0x2f] TLS_RSA_WITH_AES_128_CBC_SHA
ECDHE-ECDSA-AES256-GCM-SHA384 TLS 1.2 Modern, Compatible, Legacy [0xc02c] TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
ECDHE-ECDSA-AES256-SHA384 TLS 1.2 Compatible, Legacy [0xc024] TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
ECDHE-RSA-AES256-GCM-SHA384 TLS 1.2 Modern, Compatible, Legacy [0xc030] TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
ECDHE-RSA-AES256-SHA384 TLS 1.2 Compatible, Legacy [0xc028] TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
ECDHE-RSA-AES256-SHA TLS 1.0 Legacy [0xc014] TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
AES256-GCM-SHA384 TLS 1.2 Legacy [0x9d] TLS_RSA_WITH_AES_256_GCM_SHA384
AES256-SHA256 TLS 1.2 Legacy [0x3d] TLS_RSA_WITH_AES_256_CBC_SHA256
AES256-SHA TLS 1.0 Legacy [0x35] TLS_RSA_WITH_AES_256_CBC_SHA
DES-CBC3-SHA TLS 1.0 Legacy [0x0a] TLS_RSA_WITH_3DES_EDE_CBC_SHA
AEAD-AES128-GCM-SHA256 * TLS 1.3 Modern, Compatible, Legacy {0x13,0x01} TLS_AES_128_GCM_SHA256
AEAD-AES256-GCM-SHA384 * TLS 1.3 Modern, Compatible, Legacy {0x13,0x02} TLS_AES_256_GCM_SHA384
AEAD-CHACHA20-POLY1305-SHA256 * TLS 1.3 Modern, Compatible, Legacy {0x13,0x03} TLS_CHACHA20_POLY1305_SHA256

:::note[* TLS 1.3 minimum protocol]

Ciphers AEAD-AES128-GCM-SHA256, AEAD-AES256-GCM-SHA384, and AEAD-CHACHA20-POLY1305-SHA256 are automatically supported by your zone if you enable TLS 1.3.

TLS 1.3 uses the same cipher suite space as previous versions of TLS, but defines these cipher suites differently. TLS 1.3 only specifies the symmetric ciphers and cannot be used for TLS 1.2. Similarly, TLS 1.2 and lower cipher suites cannot be used with TLS 1.3 (RFC 8446). BoringSSL also hard-codes cipher preferences in this order for TLS 1.3. :::

Troubleshooting

import { Render } from "~/components";

If you encounter issues with edge certificate cipher suites, refer to the following scenarios.

Compatibility with Minimum TLS Version

When you adjust the setting used for your domain's Minimum TLS Version, your domain only allows HTTPS connections using that TLS protocol version. As explained in About cipher suites, although configured independently, cipher suites and TLS versions are closely related.

Minimum TLS Version can cause issues if you are not supporting TLS 1.2 ciphers on your domain. If you experience issues, review your domain's Minimum TLS Version setting and Cloudflare's supported ciphers list.

Testing Minimum TLS version with curl

Compatibility with certificate encryption

If you upload a custom certificate, make sure the certificate is compatible with the chosen cipher suites for your zone or hostname.

For example, if you upload an RSA certificate, your cipher suite selection cannot only support ECDSA certificates.

Compatibility with Cloudflare Pages

It is not possible to configure minimum TLS version nor cipher suites for Cloudflare Pages hostnames.

API requirements for custom hostname certificate

When using the Edit Custom Hostname endpoint, make sure to include type and method within the ssl object, as well as the settings specifications.

Including the settings only will result in the error message The SSL attribute is invalid. Please refer to the API documentation, check your input and try again.

TLS 1.3 settings

SSL Labs weak ciphers report

If you try to disable all of the WEAK cipher suites according to what is listed on a Qualys SSL Labs report, you might notice that the naming conventions are not the same.

This is because SSL Labs follows RFC cipher naming convention while Cloudflare follows OpenSSL cipher naming convention. The cipher suite names list in the OpenSSL documentation may help you map the names.

Even though applications on Cloudflare are not vulnerable to CVE-2019-1559, some security scanners may flag your application erroneously.

To remove these warnings, refer to Customize cipher suites and exclude the following ciphers:

Customize cipher suites via API

import { Render, TabItem, Tabs, APIRequest } from "~/components";

Prerequisites

Before you begin

Note that:

:::caution If setting up a per-hostname cipher suite customization, make sure that the hostname is specified on the certificate (instead of being covered by a wildcard). Applying a per-hostname configuration on a wildcard certificate will result in the configuration being applied to all hostnames. :::

Steps and API examples

  1. Decide which cipher suites you want to specify and which ones you want to disable (meaning they will not be included in your selection).

    Below you will find samples covering the recommended ciphers by security level and compliance standards, but you can also refer to the full list of supported ciphers and customize your choice.

  2. Log in to the Cloudflare dashboard and get your Global API Key in My Profile > API Tokens.

  3. Get the Zone ID from the Overview page of the domain you want to specify cipher suites for.

  4. Make an API call to either the Edit zone setting endpoint or the Edit TLS setting for hostname endpoint, specifying ciphers in the URL. List your array of chosen cipher suites in the value field.

<APIRequest path="/zones/{zone_id}/settings/{setting_id}" method="PATCH" json={{ value: [ "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-ECDSA-CHACHA20-POLY1305", "ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-RSA-CHACHA20-POLY1305", "ECDHE-ECDSA-AES256-GCM-SHA384", "ECDHE-RSA-AES256-GCM-SHA384", ], }} parameters={{ setting_id: "ciphers", }} />

<APIRequest path="/zones/{zone_id}/settings/{setting_id}" method="PATCH" json={{ value: [ "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-ECDSA-CHACHA20-POLY1305", "ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-RSA-CHACHA20-POLY1305", "ECDHE-ECDSA-AES256-GCM-SHA384", "ECDHE-RSA-AES256-GCM-SHA384", "ECDHE-ECDSA-AES128-SHA256", "ECDHE-RSA-AES128-SHA256", "ECDHE-ECDSA-AES256-SHA384", "ECDHE-RSA-AES256-SHA384", ], }} parameters={{ setting_id: "ciphers", }} />

:::note For compliance with PCI DSS, also enable TLS 1.3 on your zone and make sure to up your Minimum TLS version to 1.2. :::

<APIRequest path="/zones/{zone_id}/settings/{setting_id}" method="PATCH" json={{ value: [ "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES256-GCM-SHA384", "ECDHE-RSA-AES256-GCM-SHA384", "ECDHE-ECDSA-CHACHA20-POLY1305", "ECDHE-RSA-CHACHA20-POLY1305", ], }} parameters={{ setting_id: "ciphers", }} />

<APIRequest path="/zones/{zone_id}/settings/{setting_id}" method="PATCH" json={{ value: [ "AES128-GCM-SHA256", "AES128-SHA", "AES128-SHA256", "AES256-SHA", "AES256-SHA256", "DES-CBC3-SHA", "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES128-SHA", "ECDHE-ECDSA-AES128-SHA256", "ECDHE-ECDSA-AES256-GCM-SHA384", "ECDHE-ECDSA-AES256-SHA384", "ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-RSA-AES128-SHA", "ECDHE-RSA-AES128-SHA256", "ECDHE-RSA-AES256-GCM-SHA384", "ECDHE-RSA-AES256-SHA", "ECDHE-RSA-AES256-SHA384", ], }} parameters={{ setting_id: "ciphers", }} />

Reset to default values

To reset to the default cipher suites at zone level, use the Edit zone setting endpoint, specifying ciphers as the setting name in the URL, and send an empty array in the value field.

<APIRequest path="/zones/{zone_id}/settings/{setting_id}" method="PATCH" json={{ value: [], }} parameters={{ setting_id: "ciphers", }} />

For specific hostname settings, use the Delete TLS setting for hostname endpoint.

<APIRequest path="/zones/{zone_id}/hostnames/settings/{setting_id}/{hostname}" method="DELETE" parameters={{ setting_id: "ciphers", }} />

Customize cipher suites via dashboard

import { Render, Details, DashButton } from "~/components";

Prerequisites

Selection modes

When configuring cipher suites via dashboard, you can use three different selection modes:

For any of the modes, you should keep in mind the following configuration conditions. If using the security level or the compliance standard mode, some actions may be blocked and explained referencing these conditions.

* Cipher suites are used in combination with other [SSL/TLS settings](/ssl/edge-certificates/additional-options/cipher-suites/#related-ssltls-settings). * You cannot set specific TLS 1.3 ciphers. Instead, you can [enable TLS 1.3](/ssl/edge-certificates/additional-options/tls-13/#enable-tls-13) for your entire zone and Cloudflare will use all applicable [TLS 1.3 cipher suites](/ssl/edge-certificates/additional-options/cipher-suites/supported-cipher-suites/). * Each cipher suite also supports a specific algorithm (RSA or ECDSA), so you should consider the algorithms in use by your edge certificates when making your ciphers selection. You can find this information under each certificate listed on the [**Edge Certificates**](https://dash.cloudflare.com/?to=/:account/:zone/ssl-tls/edge-certificates) page. * It is not possible to configure minimum TLS version nor cipher suites for [Cloudflare Pages](/pages/) hostnames.

Steps

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. For the Cipher suites setting select Configure.

  3. Choose a mode to select your cipher suites and select Next.

  4. Select a predefined set of cipher suites or, if you opted for Custom, specify which cipher suites you want to allow. Make sure you are aware of how your selection will interact with Minimum TLS version, TLS 1.3, and the certificate algorithm (ECDSA or RSA).

  5. Select Save to confirm.

:::note[Modern or PCI DSS] When used with TLS 1.3, Modern is the same as PCI DSS. :::

[^1]: When used with TLS 1.3, Modern is the same as PCI DSS.

:::note[Testing with external scanners] Cipher suite profiles are applied per hostname. When using external scanners such as SSL Labs, ensure you are testing the exact hostname where the profile is configured. Scanning an IP address or a different hostname will return the default Cloudflare edge profile — not your custom configuration. :::

Customize cipher suites

import { Render, TabItem, Tabs, DirectoryListing } from "~/components";

With an Advanced Certificate Manager subscription, you can restrict connections between Cloudflare and clients — such as your visitor's browser — to specific cipher suites.

You may want to do this to follow specific recommendations, to disable weak cipher suites, or to comply with industry standards.

Customizing cipher suites will not lead to any downtime in your SSL/TLS protection.

:::note[Cloudflare for SaaS] If you are a SaaS provider looking to restrict cipher suites for connections to custom hostnames, this can be configured with a Cloudflare for SaaS subscription. Refer to TLS management instead. :::

How it works

Custom cipher suites is a hostname-level setting, which implies that:

Scope

Currently, you have the following options:

:::note This documentation only refers to connections between clients and the Cloudflare network. For connections between Cloudflare and your origin server, refer to Origin server > Cipher suites. :::

Settings priority and ciphers order

Cloudflare uses the hostname priority logic to determine which setting to apply.

ECDSA cipher suites are prioritized over RSA, and Cloudflare preserves the specified cipher suites in the order they are set. This means that, if both ECDSA and RSA are used, Cloudflare presents the ECDSA ciphers first - in the order they were set - and then the RSA ciphers, also in the order they were set.

Enable

import { Render, TabItem, Tabs, DashButton } from "~/components";

To enable Total TLS - which issues individual certificates for your proxied hostnames - follow these instructions:

To enable Total TLS in the dashboard:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. For Total TLS, switch the toggle to On and - if desired - choose an issuing Certificate Authority.

To enable Total TLS with the API, send a PATCH request with the enabled parameter set to your desired setting (true or false).

You can also specify a desired certificate authority by adding a value to the certificate_authority parameter.

Aspects to consider

Error messages

import { Render } from "~/components";

To help avoid ERR_SSL_VERSION_OR_CIPHER_MISMATCH errors, Cloudflare automatically shows an error message - This hostname is not covered by a certificate - on proxied DNS records not covered by a TLS certificate.

Pending domains

If you recently added your domain to Cloudflare - meaning that your zone is in a pending state - you can often ignore this warning.

Once most domains becomes Active, Cloudflare will automatically issue a Universal SSL certificate, which will provide SSL/TLS coverage and remove the warning message.

:::note

Since there are a few nuances to certificate coverage and issuance timing, review Enable Universal SSL certificates to make sure your domain will receive SSL/TLS coverage automatically.

:::

Active domains

If your zone is already active on Cloudflare, this warning identifies subdomains that are not covered by your current SSL/TLS certificate.

Total TLS

import { DirectoryListing, Render } from "~/components";

Total TLS allows Cloudflare to issue individual certificates for your proxied hostnames. These certificates will protect proxied hostnames not covered by Universal certificates.

:::caution

:::

When issued, these certificates will have a type of Advanced - Total TLS, and their default validity period is 90 days.

Reference

Availability

Total TLS is available for domains that have purchased Advanced Certificate Manager and are currently using a full DNS setup.

Limitations

Hostnames used with other Cloudflare products

Total TLS does not issue certificates for any hostnames used with:

You can use other types of certificates or manually order advanced certificates for these hostnames.

Deleting certificates

Once you enable Total TLS, be careful deleting any Total TLS certificates associated with proxied hostnames.

If you do, our system assumes you want to opt that hostname out of Total TLS certificate and will not order new certificates for the hostname in the future. This behavior applies even if you delete and re-create the hostname's DNS record.

API commands

Use the following API commands to manage advanced certificates. If you are using our API for the first time, review our API documentation.

Command Method Endpoint Additional notes
Order advanced certificate POST zones/<<ZONE_ID>>/ssl/certificate_packs/order
Restart certificate validation PATCH zones/<<ZONE_ID>>/ssl/certificate_packs/<<ID>> For a Certificate Pack in a validation_timed_out status.
Delete certificate pack DELETE zones/<<ZONE_ID>>/ssl/certificate_packs/<<ID>>
List certificate packs in a zone GET zones/<<ZONE_ID>>/ssl/certificate_packs?status=all This API call returns all certificate packs for a domain (Universal, Custom, and Advanced).
List Cipher Suite settings: Get zone setting with ciphers as the setting name in the URI path GET zones/<<ZONE_ID>>/settings/ciphers
Change Cipher Suite settings: Edit zone setting with ciphers as the setting name in the URI path PATCH zones/<<ZONE_ID>>/settings/ciphers To restore default settings, send a blank array in the value parameter.

Advanced certificates

import { DirectoryListing, GlossaryTooltip, Render, } from "~/components";


To order advanced certificates, you must purchase the Advanced Certificate Manager add-on. This add-on also unlocks the features listed below.

What the add-on includes

Advanced Certificate Manager allows you to:

:::note Enterprise customers can also purchase a subscription for Advanced Certificate Manager, which allows them to add up to 100 edge certificates per zone. :::

:::note On Partial zones, Universal SSL is provisioned per proxied hostname regardless of subdomain depth. If your only reason for considering an advanced certificate is to cover subdomains beyond the first level, Universal SSL may already be sufficient — though you'll need to proxy and validate each new hostname individually as it is added. :::

Availability

Free Pro Business Enterprise
Availability Paid add-on Paid add-on Paid add-on Paid add-on

Limitations

Advanced certificates do not apply to Cloudflare Pages or R2 custom domains. Due to certificate prioritization, these products use Cloudflare for SaaS certificates instead.

Advanced certificates are Domain Validated (DV). If your organization needs Organization Validated (OV) or Extended Validation (EV) certificates, refer to Custom certificates.

Advanced certificates cover hostnames within a single domain. If you need a certificate that spans multiple domains (a multi-domain certificate), use Cloudflare for SaaS. For architecture guidance, refer to Leveraging Cloudflare for your SaaS applications.

:::note

:::

Multi-level subdomain support

Advanced Certificate Manager supports deep, multi-level subdomains (for example, api.staging.example.com). There is no arbitrary limit on the number of subdomain levels, but you must consider the following constraints.

:::note If you want to automatically issue certificates for all proxied hostnames without manually specifying each one, enable Total TLS. :::

Domain name length limits

These limits are defined by internet standards (RFC 1035 and RFC 5280) and apply to all certificates, regardless of the certificate authority:

Wildcard coverage

Wildcard certificates only cover one subdomain level:

Hostnames per certificate

A single advanced certificate can include up to 50 hosts (SANs) total. The zone apex must be one of these 50, leaving room for up to 49 additional hostnames or wildcards.

Consistency across certificate authorities

The character-length limits above (253-character total, 63-character label, 64-character CN) are defined by IETF standards (RFC 1035, RFC 5280) and apply uniformly across all CAs. Other constraints, such as the per-certificate SAN count and supported validity periods, are Cloudflare advanced certificates limits or vary by CA. Refer to Certificate authorities for CA-specific details.

Manage advanced certificates

import { AvailableNotifications, Render, TabItem, Tabs, DashButton } from "~/components";

Create a certificate

If you are using an existing Universal SSL certificate, Cloudflare will automatically replace this certificate once you finish ordering your advanced certificate.

Once you order a certificate, you can review the certificate's status on the Edge Certificates page or via the API with a GET request.

To create a new advanced certificate in the dashboard:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. Select Order Advanced Certificate.

  3. If Cloudflare does not have your billing information, you will need to enter that information.

  4. Enter the following information:

    • Certificate authority
    • Certificate hostnames
      • For hostnames longer than 64 characters, use the API.
    • Validation method
    • Certificate validity period
  5. Select Save.

To create a new certificate using the API, send a POST request to the Cloudflare API.

If you need certificates for hostnames longer than 64 characters (RFC 5280), set the cloudflare_branding option to true. This will add sni.cloudflaressl.com in the Common Name (CN) field and will include the long hostname as a part of the Subject Alternative Name (SAN).

:::caution

:::


Delete a certificate

To delete an advanced certificate in the dashboard:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. Select a certificate.

  3. Select Delete Certificate.

To delete a certificate using the API, send a DELETE request to the Cloudflare API.


Restart validation

To restart validation for a certificate in a validation_timed_out status, send a PATCH request to the API.


Restrict cipher suites

For more details, refer to Customize cipher suites.


Perform domain control validation (DCV)


Normally, you only need to update DCV if you have your application on a partial setup (Cloudflare does not run your authoritative nameservers).

For more information about DCV, refer to DCV methods.


Set up alerts

You can configure alerts to receive notifications for changes in your certificates.


Advanced certificate renewal

The certificate validity period you choose determines when the auto renewal will start for your certificate. For details, refer to Validity period and renewal.

Domain control validation flow

import { Render } from "~/components";

To obtain Universal, Advanced, and Custom hostname certificates, Cloudflare partners with different publicly trusted certificate authorities (CAs).

However, every time a CA is requested to issue or renew a certificate, the requester must prove that they have control over the domain. That is when the DCV process takes place, with the proof usually consisting of placing an HTTP token at a standard URL path (/.well-known/pki-validation), or placing a TXT record at the authoritative DNS provider.

Where Cloudflare sits in the DCV process

For the use cases mentioned above, there are three different parties involved in the process:

Steps in the process

In summary, five steps have to succeed after Cloudflare requests a CA to issue or renew a certificate:

  1. Cloudflare receives the DCV tokens from the CA.
  2. Cloudflare either places the tokens on your behalf (Full DNS setup, Delegated DCV), or makes the tokens available for you to place them.
  3. Cloudflare polls the validation URLs to check for the tokens.
  4. After Cloudflare can confirm that the tokens are placed via multiple DNS resolvers, the CA is asked to check as well.
  5. If the CA can confirm the tokens are placed, the certificate gets issued. If the CA cannot confirm the tokens are placed, the certificate is not issued and the tokens are no longer valid.

Aspects to consider

DCV tokens

DCV tokens are generated and controlled by the CA and not by Cloudflare. You can find further technical specification of how they work in RFC 8555.

Domain control validation (DCV)

import { Render } from "~/components";

If DCV is not completed, the CA cannot issue or renew the certificate, and visitors to your site will see SSL/TLS errors.

:::note

Refer to Domain control validation flow to learn more about the steps and parties involved in the DCV process.

:::

For custom certificates, you handle DCV directly with the CA when requesting or renewing the certificate.

For certificates issued through Cloudflare, whether DCV is automatic depends on your DNS setup.


Full DNS setup - no action required

If your domain is on a full setup — meaning that Cloudflare runs your authoritative nameservers — Cloudflare handles DCV automatically on your behalf using a TXT record. For more details, refer to Enable Universal SSL.


Partial DNS setup - action sometimes required

If your application is on a partial DNS setup — meaning that Cloudflare does not run your authoritative nameservers — you may need to perform additional steps to complete DCV.

Non-wildcard certificates

Wildcard certificates

Troubleshooting

import { GlossaryTooltip, Render, Tabs, TabItem } from "~/components";

If your certificate is stuck in Pending Validation or failing to issue, the certificate authority (CA) may be unable to complete domain control validation (DCV). This page helps you identify and resolve common DCV issues.

:::note If you are using the Cloudflare API, error messages are presented under the validation_errors parameter. :::

Quick checklist

Use this checklist to identify common DCV issues:


Blocked validation URL

If you have issues while HTTP DCV is in place, review the following settings:

Redirection

Enabling Always Use HTTPS does not impact the validation process.

In a Partial (CNAME) setup where you are managing the token on the origin side, please ensure that no redirection from HTTP to HTTPS occurs on the /.well-known/* path.

When using Redirect Rules, exclude the /.well-known/* path from redirections by adding a condition to your rule:

not starts_with(http.request.uri.path, "/.well-known/")

For example, if you have a rule that redirects all HTTP traffic to HTTPS, modify the rule expression to:

(http.request.scheme eq "http") and not starts_with(http.request.uri.path, "/.well-known/")

DNS settings and records

The errors below refer to situations that have to be addressed at the authoritative DNS provider:

Consider the following when troubleshooting:

CAA records

You can check the CAA records by running the following command:

dig example.com CAA +short
Resolve-DnsName -Name example.com -Type CAA

Stale or conflicting DCV records

When Cloudflare handles TXT validation for you (full setup or Delegated DCV), Cloudflare adds _acme-challenge TXT records when it requests a certificate from a certificate authority. Records from a previous or abandoned certificate order can persist and may not appear under DNS > Records in the dashboard.

Review the following symptoms:

To confirm, query the record from your authoritative nameservers:

dig _acme-challenge.example.com TXT +short @<AUTHORITATIVE_NAMESERVER>

Compare each value that dig returns with the tokens listed for your certificates that are pending validation (refer to Get DCV values). If a value matches none of them and you can find the record in your DNS settings (under DNS > Records, or at your external DNS provider), it is yours to remove. If a value matches none of them and you cannot find the record in your DNS settings, contact Cloudflare Support to have the stale records removed. After the records are removed, you can send a PATCH request to the validation endpoint using the same DCV method to trigger revalidation.

Certificate authority (CA) errors

A certificate authority (CA) is the organization that issues your SSL/TLS certificate. Cloudflare partners with multiple CAs to provide certificates for your domain.

:::note Selecting a different CA is only available with Advanced Certificate Manager or SSL for SaaS. Universal SSL customers cannot change the CA. :::

Rate limiting

When you see The authority has rate limited these domains. Please wait for the rate limit to expire or try another authority, the certificate authority has temporarily blocked certificate issuance for your domain due to too many recent requests.

Rate limit windows vary by CA:

Resolution: Wait for the rate limit window to expire, or select a different CA.

CAA records block issuance

The error CAA records block issuance. Please remove all CAA records or add records for this authority indicates that your domain's CAA records do not allow the selected certificate authority to issue certificates.

Resolution: Either remove all CAA records from your domain, or add CAA records that explicitly allow Cloudflare's partner certificate authorities.

Multiple perspective validation errors

Certificate authorities perform domain validation from multiple geographic locations to prevent certain attacks. You may encounter one of these errors:

Resolution: Ensure your DNS records (including CAA records) are consistently resolvable from all geographic locations. You can investigate resolution errors using the ping.pe tool. For example, for a Google Trust Services certificate, check: <hostname>:CAA:8.8.8.8.

Read more from certificate authority documentation: SSL.com, Let's Encrypt, and Google Trust Services.

DNS lookup errors

The error the Certificate Authority had trouble performing a DNS lookup indicates that the CA could not resolve your domain's DNS records. Common causes include SERVFAIL responses, NXDOMAIN, or DNSSEC validation failures.

Resolution: Verify that your DNS records are correctly configured and resolvable. Use tools like DNSViz to check for DNSSEC issues, and ensure your authoritative nameservers are responding correctly.

Rejected identifier

The error The certificate authority will not issue for this domain. Please check your input or try another authority means the CA has policies that prevent issuing certificates for your specific domain.

Resolution: Verify that your domain name is correctly spelled and does not violate the CA's issuance policies. If the domain is valid, try selecting a different CA.

Internal errors

When you see Internal error with Certificate Authority. Please check later, the certificate authority encountered a temporary issue during validation.

Resolution: Wait a few minutes and retry. If the issue persists, try selecting a different CA. Cloudflare will automatically retry validation according to the validation backoff schedule.


DCV token values changed

DCV tokens are generated by the certificate authority (CA), not by Cloudflare. If the token value you previously retrieved is no longer accepted, it may have changed for one of these reasons:

Reason Details
Token expiry CA tokens have a fixed validity period defined by the CA/B Baseline Requirements. After this period, Cloudflare generates new tokens automatically.
Validation failure If a DCV check fails, the current token may become invalid and Cloudflare generates a replacement. Refer to DCV tokens for details on when this occurs.

CA tokens have the following validity periods:

Certificate authority Token validity
Google Trust Services 14 days
Let's Encrypt 7 days
SSL.com 14 days

In both cases — expiry and failure — the token value changes. If you are managing DCV manually, always retrieve the current token value via the SSL Verification API immediately before placing or updating your DNS record. Do not reuse a previously noted token value.

To trigger an immediate DCV recheck after placing your record — rather than waiting for Cloudflare's next scheduled attempt — use the Edit SSL Certificate Pack Validation Method endpoint, specifying the same validation_method you are currently using.

Refer to Validation backoff schedule for the full retry schedule and token validity details.

:::tip To avoid managing DCV tokens manually, consider using Delegated DCV. With Delegated DCV, Cloudflare handles token rotation automatically on your behalf, so token expiry and validation failures no longer require manual intervention. :::


Validation method changed to TXT

If you expected HTTP DCV but received a TXT token instead — or if you configured HTTP DCV and later found it had changed to TXT — one of the following conditions applies:

HTTP DCV not available for your certificate

Some certificate configurations cannot use HTTP DCV regardless of your preference:

HTTP DCV configured but falling back to TXT over time

If you are using HTTP DCV in a partial DNS setup and managing DCV tokens manually, Cloudflare falls back to TXT after HTTP DCV fails continuously for a period that depends on the certificate validity period:

Once the fallback occurs, Cloudflare generates TXT tokens that you must place manually at your authoritative DNS provider. To understand why HTTP DCV is failing, refer to Blocked validation URL and Redirection.

Certificate renewal falling back to TXT

At certificate renewal, Cloudflare always attempts HTTP DCV first, regardless of the method used at initial issuance. Renewal completes automatically via HTTP only if all of the following conditions are met:

If any condition is not met, renewal falls back to your configured method and you must manually place new DCV records. Renewal tokens are generated 30 days before certificate expiry.

To avoid manual renewal steps in a partial setup, consider using Delegated DCV, which lets Cloudflare manage DCV on your behalf even when you control the authoritative DNS.

Validation backoff schedule

import { Render } from "~/components";

Domain control validation (DCV) has to happen before a certificate authority (CA) will issue a certificate for a domain. If DCV fails during issuance or renewal, Cloudflare automatically retries it on a schedule.

If you use Delegated DCV or if Cloudflare automatically performs DCV for you, this page is only informational. If you have to manually perform DCV, consider the following sections about the validation schedule and remember that DCV tokens have a fixed validity period.

:::note

You can also request an immediate recheck by using the Edit SSL Certificate Pack Validation Method endpoint, specifying the same validation_method as the method you currently use. :::


DCV tokens validity

The DCV process relies on tokens that are generated by the issuing certificate authority. These tokens have a validity period defined by each CA:

After this period, DCV tokens expire as dictated by the CA/B Baseline Requirements, and new, valid tokens must be placed.

:::caution

:::

Successive checks function

Cloudflare caps the check backoff to a maximum of four hours to avoid the function growing exponentially, which would result in large gaps between checks towards the end of the month.

now() + min((floor(60 * pow(1.05, retry_attempt)) * INTERVAL '1 second'), INTERVAL '4 hours')

Capped attempts reference table

As presented in the following table, most of the checks take place on the first day after the DCV token is generated.

In manual processes, it is possible that you fall behind schedule when you place the token, meaning that it may not be validated immediately.

In automatic processes, most validations complete within the first five minutes, unless there is a setup misconfiguration.

Cloudflare for SaaS

For custom hostnames, the same backoff schedule applies to automatic DCV retries. If you need to trigger an immediate recheck — for example, after your customer has placed the DCV token — send a PATCH request to the custom hostname with the current ssl settings. This resets the backoff timer and triggers a new validation attempt immediately.

Retry Attempt In Seconds In Minutes In Hours
0 60 1.000 0.016667
1 63 1.050 0.017500
2 66 1.100 0.018333
3 69 1.150 0.019167
4 72 1.200 0.020000
5 76 1.267 0.021111
6 80 1.333 0.022222
7 84 1.400 0.023333
8 88 1.467 0.024444
9 93 1.550 0.025833
10 242 4.033 0.067222
11 279 4.650 0.077500
12 321 5.350 0.089167
13 369 6.150 0.102500
14 424 7.067 0.117778
15 488 8.133 0.135556
16 561 9.350 0.155833
17 645 10.750 0.179167
18 742 12.367 0.206111
19 853 14.217 0.236944
20 981 16.350 0.272500
21 1129 18.817 0.313611
22 1298 21.633 0.360556
23 1493 24.883 0.414722
24 1717 28.617 0.476944
25 1975 32.917 0.548611
26 2271 37.850 0.630833
27 2612 43.533 0.725556
28 3003 50.050 0.834167
29 3454 57.567 0.959444
30 3972 66.200 1.103333
31 4568 76.133 1.268889
32 5253 87.550 1.459167
33 6041 100.683 1.678056
34 6948 115.800 1.930000
35 7990 133.167 2.219444
36 9189 153.150 2.552500
37 10567 176.117 2.935278
38 12152 202.533 3.375556
39 13975 232.917 3.881944
40 14400 240.000 4.000000
41 14400 240.000 4.000000
42 14400 240.000 4.000000
43 14400 240.000 4.000000
44 14400 240.000 4.000000
45 14400 240.000 4.000000
46 14400 240.000 4.000000
47 14400 240.000 4.000000
48 14400 240.000 4.000000
49 14400 240.000 4.000000
50 14400 240.000 4.000000
51 14400 240.000 4.000000
52 14400 240.000 4.000000
53 14400 240.000 4.000000
54 14400 240.000 4.000000
55 14400 240.000 4.000000
56 14400 240.000 4.000000
57 14400 240.000 4.000000
58 14400 240.000 4.000000
59 14400 240.000 4.000000
60 14400 240.000 4.000000
61 14400 240.000 4.000000
62 14400 240.000 4.000000
63 14400 240.000 4.000000
64 14400 240.000 4.000000
65 14400 240.000 4.000000
66 14400 240.000 4.000000
67 14400 240.000 4.000000
68 14400 240.000 4.000000
69 14400 240.000 4.000000
70 14400 240.000 4.000000
71 14400 240.000 4.000000
72 14400 240.000 4.000000
73 14400 240.000 4.000000
74 14400 240.000 4.000000
75 14400 240.000 4.000000
76 14400 240.000 4.000000
77 14400 240.000 4.000000
78 14400 240.000 4.000000
79 14400 240.000 4.000000
80 14400 240.000 4.000000
81 14400 240.000 4.000000
82 14400 240.000 4.000000
83 14400 240.000 4.000000
84 14400 240.000 4.000000
85 14400 240.000 4.000000
86 14400 240.000 4.000000
87 14400 240.000 4.000000
88 14400 240.000 4.000000
89 14400 240.000 4.000000
90 14400 240.000 4.000000
91 14400 240.000 4.000000
92 14400 240.000 4.000000
93 14400 240.000 4.000000
94 14400 240.000 4.000000
95 14400 240.000 4.000000
96 14400 240.000 4.000000
97 14400 240.000 4.000000
98 14400 240.000 4.000000
99 14400 240.000 4.000000
100 14400 240.000 4.000000
101 14400 240.000 4.000000
102 14400 240.000 4.000000
103 14400 240.000 4.000000
104 14400 240.000 4.000000
105 14400 240.000 4.000000
106 14400 240.000 4.000000
107 14400 240.000 4.000000
108 14400 240.000 4.000000
109 14400 240.000 4.000000
110 14400 240.000 4.000000
111 14400 240.000 4.000000
112 14400 240.000 4.000000
113 14400 240.000 4.000000
114 14400 240.000 4.000000
115 14400 240.000 4.000000
116 14400 240.000 4.000000
117 14400 240.000 4.000000
118 14400 240.000 4.000000
119 14400 240.000 4.000000

Delegated

import { Example, Render } from "~/components";

Delegated DCV allows zones with partial DNS setups - meaning authoritative DNS is not provided by Cloudflare - to delegate the DCV process to Cloudflare.

DCV Delegation requires you to place a one-time record that allows Cloudflare to auto-renew all future certificate orders, so that there’s no manual intervention at the time of the renewal.

:::note

DCV Delegation will not work with Universal Certificates and requires the use of an Advanced certificate. :::

Availability

Free Pro Business Enterprise
Availability Included with Advanced Certificate Manager Included with Advanced Certificate Manager Included with Advanced Certificate Manager Included with Advanced Certificate Manager

When to use

You should use Delegated DCV when all of the following conditions are true:

Aspects to keep in mind

As explained in the announcement blog post, currently, you can only delegate DCV to one provider at a time. This means:

Setup

To set up Delegated DCV:

  1. Order an advanced certificate for your zone, choosing TXT as the Certificate validation method.
  2. On the Edge Certificates page, go to DCV Delegation for Partial Zones.
  3. Copy the Cloudflare validation URL.
  4. At your authoritative DNS provider, create CNAME record(s) considering the following:
_acme-challenge.example.com CNAME example.com.<COPIED_VALIDATION_URL>.

For example, a certificate covering example.com, *.example.com, and sub.example.com would require the following records.

_acme-challenge.example.com CNAME example.com.<COPIED_VALIDATION_URL>.
_acme-challenge.sub.example.com CNAME sub.example.com.<COPIED_VALIDATION_URL>.

Once the CNAME records are in place, Cloudflare will add TXT DCV tokens for every hostname on the Advanced certificate that has a DCV delegation record in place, as long as the zone is active on Cloudflare.

Because DCV happens regularly, do not remove the CNAME record(s) at your authoritative DNS provider. Otherwise, Cloudflare will not be able to perform DCV on your behalf and your certificate will not be issued.

Further details

Testing

If you use a dig command to test, you should only be able see the placed tokens if the certificate is up for issuance.

This is because Cloudflare places the tokens when needed and then cleans them up.

dig TXT +noadditional +noquestion +nocomments +nocmd +nostats _acme-challenge.example.com. @1.1.1.1

_acme-challenge.example.com. 3600    IN    CNAME    example.com.<COPIED_VALIDATION_URL>

Renewal

If a hostname becomes unreachable during certificate renewal time, the certificate will not be able to be renewed automatically via Delegated DCV. Should you need to renew a certificate for a hostname that is not resolving currently, you can send a PATCH request to the changing DCV method API endpoint and change the method to TXT to proceed with manual renewal per the TXT DCV method.

Once the hostname becomes resolvable again, Delegated DCV will resume working as expected.

Moved domains

If you move your zone to another account, you will need to update the CNAME record at your authoritative DNS provider with a new validation URL.

HTTP

import { Details, Render } from "~/components";

When you choose HTTP DCV, Cloudflare automatically adds a verification HTTP token to your domain.

Only use this method if your domain can tolerate a few minutes of downtime.

:::note

If you encounter issues with HTTP DCV, refer to the troubleshooting guide.

:::

Limitations

HTTP DCV is only available for proxied domains. It is possible to manually add the DCV token to the .well-known/pki-validation/ directory on your origin web server to pre-validate your certificates.

HTTP DCV validation does not work for wildcard certificates. If you want to use wildcard certificates, use TXT validation.

Based on your chosen certificate authority (CA), you may also not be able to use HTTP verification with advanced certificates.

Setup

Specify DCV method

In either case, you would need to set a "validation_method":"http" parameter.

Review other Cloudflare settings

To make sure your domain does not accidentally block HTTP DCV, review your Cloudflare settings for common setup issues.

Complete DCV

Your HTTP token will be available for the certificate authority as soon as you finish your partial domain setup.

This means that you need to add a CNAME record to Cloudflare in your authoritative DNS and create proxied DNS records for your hostname within Cloudflare.

This process may involve a few minutes of downtime.

Renewal

If the conditions are met but HTTP DCV fails successively, the process will fall back to TXT. This schedule varies according to the certificate validity period.

Methods

import { DirectoryListing, Render } from "~/components";

Perform DCV

For details on each method available for DCV, refer to the following resources:

:::note

For guidance on when you need to perform DCV, refer to Domain Control Validation.

:::


Verify DCV status

To verify the DCV status of a certificate, either monitor the certificate's status on the Edge Certificates page or use the Verification Status endpoint.

A status of active means that the certificate has been deployed to Cloudflare’s global network and will be served as soon as HTTP traffic is proxied to Cloudflare.

Update DCV methods

You cannot update the DCV method for an active certificate. To update the DCV method for a subdomain, wait until the DCV expires and then change the DCV method.

[^1]: Meaning that Cloudflare is your Authoritative DNS provider.

[^2]: Meaning that another DNS provider - not Cloudflare - maintains your Authoritative DNS.

TXT

import { Render, TabItem, Tabs } from "~/components";



When to use

Generally, you need to perform TXT-based DCV when your certificate requires DCV and you cannot perform Delegated DCV.


Setup

Specify DCV method

Get DCV values

Update DNS records

At your authoritative DNS provider, create a TXT record named the txt_name and containing the txt_value.

Repeat this process for all the DCV records returned in the validation_records field to your Authoritative DNS provider.

If one or more of the hostnames on the certificate fail to validate, the certificate will not be issued or renewed.

This means that a wildcard certificate covering example.com and *.example.com will require two DCV tokens to be placed at the authoritative DNS provider. Similarly, a certificate with five hostnames in the SAN (including a wildcard) will require five DCV tokens to be placed at the authoritative DNS provider. Certificates with several packs (RSA and ECDSA for example) may also require several DCV tokens.

Complete DCV

Once you update your DNS records, you can either wait for the next retry or request an immediate recheck.

TXT records used for DCV can be removed from your authoritative DNS provider as soon as the certificate is issued.

Renewal

[^2]: Meaning that another DNS provider - not Cloudflare - maintains your Authoritative DNS.

Bundle methodologies

import { Tabs, TabItem } from "~/components";

When an SSL certificate is deployed to Cloudflare's global network, it may be augmented with intermediate and root certificates to assist the user agent in finding a chain to a publicly trusted root.

You can control the mechanics of how certificates are bundled by specifying a bundling methodology.

Intermediate and root certificates

Cloudflare maintains intermediate and root certificates used for bundling on a GitHub repository. As the certificates expire or are removed by certificate authorities, Cloudflare removes and adds them accordingly.

Expiration values for these certificates may appear in the expires_on field when you use the Analyze Certificate endpoint - often when the methodology you specify is Compatible. However, these expiration values reflect intermediate and root certificates - which are handled by Cloudflare -, not the leaf certificate you would have previously uploaded to Cloudflare.

:::note When using compatible or modern, a selection might be done on the intermediates you provide at upload time, meaning it is not guaranteed all of them will make it to the final chain. If you must ensure the chain you upload is the one used, select user-defined. :::

Methodologies

Compatible

Compatible is the default methodology and uses common and well distributed intermediate certificates to complete the chain. This ensures that the resulting bundle is compatible with as many clients as possible.

Modern

Modern consists of attempts to make the chain as efficient as possible, often by using newer or fewer intermediate certificates.

User-defined

User-defined allows you to paste your own certificate chain and present that bundle to clients. If you are using a self-signed certificate (not recommended), you must use this mode.

Custom certificates

import { Render } from "~/components";


Use custom certificates when you need control over the certificate authority (CA) or require Organization Validated (OV) or Extended Validation (EV) certificates that Cloudflare-managed options do not support.

Unlike Universal SSL or advanced certificates, Cloudflare does not manage issuance and renewal for custom certificates. You are responsible for the following:

:::note

If your custom certificate does not cover all of your first-level hostnames, you can enable Universal SSL certificate to cover them.

If your custom certificate is from a certificate authority that Cloudflare partners with, consider switching to a Cloudflare-managed certificate to benefit from automatic issuance and renewal.

:::

Certificate packs

Each pack only counts as one SSL certificate against your custom certificate quota.

:::note

You cannot delete the primary certificate if secondary certificates are present in the pack.

:::

Availability

Free Pro Business Enterprise
Availability No No Yes Yes
Certificate packs included 0 0 5 Modern and 1 Legacy 5 Modern (can purchase more) and 1 Legacy (can purchase more)

Certificate Signing Requests (CSRs)

You can use Cloudflare to generate a Certificate Signing Request (CSR) for your custom certificate. When you do, Cloudflare generates and securely stores the private key associated with the CSR.

Geo Key Manager (private key restriction)

By default, Cloudflare encrypts and securely distributes private keys to all Cloudflare data centers, where they can be used for local SSL/TLS termination. If you want to restrict where your private keys may be used, use Geo Key Manager.

Keyless SSL

If you want to upload a custom certificate but retain your private key on your own infrastructure, consider using Keyless SSL.

Certificate pinning

Custom certificates are the only certificate type where certificate pinning can work on Cloudflare. For guidance on pinning and its risks, refer to Certificate pinning.

Remove key file password

import { Details } from "~/components";

You cannot upload a custom certificate with a password-protected key file.

The process for removing the password depends on your operating system. The following examples remove the password from example.com.key.

  1. Open a command console.

  2. Go to the directory containing the example.com.key file.

  3. Copy the original key.

    cp example.com.key temp.key
    
  4. Run the following command (if using an ECDSA certificate, replace rsa with ec).

    openssl rsa -in temp.key -out example.com.key
    
  5. When prompted in the console window, enter the original key password.

  6. Upload the file contents to Cloudflare.

  1. Go to https://indy.fulgan.com/SSL/ and download the latest version of OpenSSL for your x86 or x86_64 operating system.

  2. Open the .zip file and extract it.

  3. Select openssl.exe.

  4. In the command window that appears, run:

    rsa -in C:\Path\To\example.com.key -out key.pem
    
  5. Enter the original key password when prompted by the openssl.exe command window.

  6. Upload the contents of the key.pem file to Cloudflare.

Renewal and expiration

import { GlossaryTooltip, DashButton } from "~/components"

Renew custom certificates

Since Cloudflare cannot renew uploaded certificates, you should ensure that you replace or update an expiring custom certificate before it expires, otherwise your visitors may not be able to connect.

Cloudflare automatically sends email notifications 30 and 14 days before your custom certificate expires. The email is sent to users who have the SSL/TLS, Administrator, or Super Administrator roles.

These notifications are reminders only. Cloudflare cannot renew an uploaded certificate for you — to maintain coverage, upload a replacement before the current certificate expires.

:::note

When renewing a custom certificate, you can reuse a previously generated CSR.

If you are on an Enterprise plan and want to renew a custom (modern) certificate, consider requesting access to Staging environment (Beta). :::

Expired certificates

If a valid replacement - covering some or all of the SANs in the expiring custom certificate - is already available, Cloudflare will remove the expiring custom certificate in the 24 hours before expiration. There is no expected downtime due to certificate transition.

If no valid replacement is available, Cloudflare will remove the custom certificate after it expires.

Affected domains and subdomains will fall back to any other active certificate covering the hostnames on the expiring certificate.

:::caution

All certificates in a certificate pack are treated as one object. The expiration date of a certificate pack is equivalent to the soonest Not After date among the certificates in the pack.

For example if you have a custom certificate made of an ECSDA and a RSA certificate, if one of them expires the whole pack will be removed. :::

Migrate to other certificate types

If you no longer want to use your custom certificate but still want your website or application to be covered with SSL/TLS, you can do the following:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. Make sure there is already an active universal or advanced certificate covering the same hostnames.

  3. Delete your custom certificate.

Troubleshooting

Make sure your key and certificate match

You can use an external tool such as the SSLShopper Certificate Key Matcher to check your certificate and make sure the key matches.

Alternatively, use openssl to verify the match by comparing the public key hash of both files. This method works for both RSA and ECDSA certificates:

openssl x509 -noout -pubkey -in certificate.crt | openssl md5
openssl pkey -pubout -in private.key | openssl md5

If the two outputs match, the certificate and key are a valid pair.

Check the certificate details

You can use openssl to check all the details of your certificate:

openssl x509 -in certificate.crt -noout -text

Then, make sure all the information is correct before uploading.

Remove password from private key

Cloudflare does not accept password-protected private keys. If your private key requires a password, remove it before uploading. The following command works for both RSA and ECDSA keys:

openssl pkey -in protected.key -out unprotected.key

Use the unprotected.key file when uploading to Cloudflare. For detailed instructions, refer to Remove key file password.

Private key format requirements

Private keys must be in one of the following unencrypted formats:

Moved domains

If you move a domain without deleting the custom certificate from the previous zone, the certificate may still take precedence and be presented to your visitors, until the previous zone is deleted.

Refer to Move a domain between Cloudflare accounts for details.

Let's Encrypt chain update

As Let's Encrypt - one of the certificate authorities (CAs) used by Cloudflare - has announced changes in its chain of trust, you may face issues.

If you are using a Let's Encrypt certificate uploaded by yourself as a custom certificate, consider the following:

Error codes

Invalid certificate. (Code: 1002)

Root cause

The certificate you are trying to upload is invalid. For example, there might be extra lines, or the BEGIN/END text is not correct, or extra characters are added following a copy/paste.

In the case of an update with the PATCH API call, it can mean the path parameter {custom_certificate_id} is invalid.

Solution

Carefully check the content of the certificate. You may use openssl to check all the details of your certificate:

openssl x509 -in certificate.crt -noout -text

When using the API, carefully check the {custom_certificate_id} path parameter. You can confirm the certificate ID by listing the existing custom certificates (id in the response).

You have reached the maximum number of custom certificates. (Code: 1212)

Root cause

You have used up your custom certificate quota.

Solution

If you are renewing an existing certificate, update the existing certificate instead of uploading a new one. Updating an existing certificate via the dashboard (or the API PATCH method) reuses its quota slot and avoids downtime.

If you genuinely need a new certificate for a different hostname, delete an unused certificate first or contact your account team (Enterprise) to increase your quota.

:::caution Deleting a certificate removes it from Cloudflare's edge immediately. If no other certificate covers the same hostnames, visitors will see TLS errors until a replacement is uploaded and active. :::

This certificate has already been submitted. (Code: 1220)

Root cause

You are trying to upload a custom certificate that you have already uploaded.

Solution

If you are renewing the certificate with updated expiry or key material, update the existing certificate instead of uploading a new one. Updating via the dashboard (or the API PATCH method) avoids downtime and does not consume an additional quota slot.

You already have a certificate of this signature type. (Code: 1228)

Root cause

A custom certificate pack can only have one certificate per signature algorithm (for example, one RSA and one ECDSA certificate).

Solution

Instead of uploading a new certificate, update the existing certificate using the edit option in the dashboard or the PATCH API endpoint.

This certificate cannot be deleted at this time. (Code: 1305)

Root cause

This error occurs when there is an issue with the certificate pack structure. You must delete other certificates in the pack before deleting this one.

Solution

Delete the other certificates in the certificate pack first, then delete this certificate. If the issue persists, contact Cloudflare Support.

Only root CA certificate is allowed. (Code: 1411)

Root cause

You are trying to upload a certificate to the custom origin trust store, but the certificate is not a valid root CA certificate.

Solution

When creating a self-signed root CA certificate, ensure you use the -extensions v3_ca option with OpenSSL. Refer to this community post for more details.

The SSL attribute is invalid. Please refer to the API documentation, check your input and try again. (Code: 1434)

Root cause

You are trying to upload a custom certificate that does not support any cipher that is needed by Chromium-based browsers.

Solution

Modify the certificate so that it supports chromium-supported ciphers and try again.

You have reached your quota for the requested resource. (Code: 2005)

Root cause

The quota for custom certificates depends on the type of certificate (Custom Legacy vs Custom Modern).

If you try to upload a certificate type but have already reached your quota, you will receive this error.

Solution

First, check your custom certificate entitlements on the Edge Certificates page.

Then, when actually uploading or editing the certificate, make sure you select the appropriate option for Legacy Client Support.

The certificate chain you uploaded cannot be bundled using Cloudflare's trust store. Please check your input and try again. (Code: 2100)

Root cause

You are trying to upload a custom certificate that contains the root and leaf certificate at the same time.

Solution

Upload the leaf certificate only.

The certificate chain you uploaded has no leaf certificates. Please check your input and try again. (Code: 2101)

Root cause

You are trying to upload a root + intermediate + intermediate .crt file, but the actual leaf certificate is in a separate file.

Solution

Add the leaf to the .crt file, or just use the leaf by itself since the Certificate Authority has a public chain of trust in our trust store.

The certificate chain you uploaded does not include any hostnames from your zone. Please check your input and try again. (Code: 2103)

Root cause

Cloudflare verifies that uploaded custom certificates include a hostname for the associated zone. Moreover, this hostname must be included as a Subject Alternative Name (SAN). This is following the standard set by the CA/Browser Forum.

Solution

Make sure your certificate contains a Subject Alternative Name (SAN) specifying a hostname in your zone. You can use the openssl command below and look for Subject Alternative Name in the output.

openssl x509 -in certificateFile.pem -noout -text

If it does not exist, you will need to request a new certificate.

The private key you uploaded is invalid. Please check your input and try again. (Code: 2106)

Root cause

Cloudflare requires separate, pem-encoded files for the SSL private key and certificate.

Solution

Contact your Certificate Authority (CA) to confirm whether your current certificate meets this requirement or request your CA to assist with certificate format conversion.

Make sure your certificate complies with these requirements.

Check that the certificate and private keys match before uploading the certificate in the Cloudflare dashboard. This external resource might help.

The certificate and private key pair you uploaded is invalid. (Code: 2200)

Root cause

The certificate and private key you uploaded do not form a valid pair. The private key does not correspond to the public key in the certificate. This can happen when the wrong key file is selected during upload.

Solution

Ensure the private key corresponds to the certificate you are uploading. You can verify this by comparing the public key hash of both files. This method works for both RSA and ECDSA certificates:

openssl x509 -noout -pubkey -in certificate.crt | openssl md5
openssl pkey -pubout -in private.key | openssl md5

If the outputs do not match, you have mismatched the certificate and key.

An unknown error has occurred. (Code: 2000)

Root cause

An internal error occurred while processing your request.

Solution

Wait a few minutes and try again. If the issue persists, contact Cloudflare Support with a HAR file capturing the failed upload attempt.

Manage custom certificates

import { Details, GlossaryTooltip, Render, TabItem, Tabs, APIRequest, DashButton, } from "~/components";

This page lists Cloudflare requirements for custom certificates and explains how to upload and update these certificates using Cloudflare dashboard or API.

Certificate requirements

Before accepting custom certificates, Cloudflare parses them and checks for validity according to a list of requirements.

Each custom certificate you upload must:


Upload a custom certificate

:::caution When using compatible or modern bundling, make sure to upload only the leaf certificate. This will allow Cloudflare to properly handle the expiration of intermediate and root certificates. :::

To upload a custom SSL certificate in the dashboard:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. In Edge Certificates, select Upload Custom SSL Certificate.

  3. Copy and paste relevant values into SSL Certificate and Private key text areas (or select Paste from file).

    :::note If doing this manually, include the ---BEGIN CERTIFICATE--- and ---END CERTIFICATE--- like the placeholder text. :::

  4. Choose the appropriate Bundle Method.

  5. Select a value for Private Key Restriction.

  6. Select a value for Legacy Client Support, which specifies Server Name Indication (SNI) support:

    • Modern (recommended): SNI only

    • Legacy: Supports non-SNI :::caution

      Custom certificates of the type legacy_custom are not compatible with BYOIP. :::

  7. Select Upload Custom Certificate. If you see an error for The key you provided does not match the certificate, contact your Certificate Authority to ensure the private key matches the certificate.

  8. (optional) Add a CAA DNS record.

The following call will upload a certificate for use with app.example.com. Cloudflare will automatically bundle the certificate with a certificate chain optimized for maximum compatibility with browsers.

:::caution

Note that if you are using an ECC key generated by OpenSSL, you will need to first remove the -----BEGIN EC PARAMETERS-----...-----END EC PARAMETERS----- section of the file. :::

  1. Update the file and build the payload
request_body=$(< <(cat <<EOF
{
  "certificate": "$MYCERT",
  "private_key": "$MYKEY",
  "bundle_method": "ubiquitous"
}
EOF
))

You can optionally add geographic restrictions that specify where your private key can physically be decrypted:

request_body=$(< <(cat <<EOF
{
  "certificate": "$MYCERT",
  "private_key": "$MYKEY",
  "bundle_method": "ubiquitous",
  "geo_restrictions": {"label": "us"}'
}
EOF
))

You can also enable support for legacy clients which do not include SNI in the TLS handshake.

request_body=$(< <(cat <<EOF
{
  "certificate": "$MYCERT",
  "private_key": "$MYKEY",
  "bundle_method": "ubiquitous",
  "geo_restrictions": {"label": "us"}',
  "type":"sni_custom"
}
EOF
))

sni_custom is recommended by Cloudflare. Use legacy_custom when a specific client requires non-SNI support. The Cloudflare API treats all Custom SSL certificates as Legacy by default.

:::caution

Custom certificates of the type legacy_custom are not compatible with BYOIP. :::

  1. Upload your certificate and key

Use the POST endpoint to upload your certificate and key.

curl https://api.cloudflare.com/client/v4/zones/{zone_id}/custom_certificates \
--header "X-Auth-Email: <EMAIL>" \
--header "X-Auth-Key: <API_KEY>" \
--header "Content-Type: application/json" \
--data "$request_body"
  1. (Optional) Add a CAA record.

For more guidance, refer to Create a CAA record.


Update or renew an existing custom certificate

To renew a custom certificate that is approaching expiry, or to replace a certificate with updated key material, follow the steps below. This is the recommended renewal path — it does not consume an additional certificate quota slot and avoids downtime.

Before you update an existing custom certificate, you might want to consider having active universal or advanced certificates as fallback options. Go to the Edge Certificates page to check a list of hostnames and status of the edge certificates in your zone.

If you are on an Enterprise plan and want to update a custom (modern) certificate, also consider requesting access to Staging environment (Beta).

Replacing a custom certificate following these steps does not lead to any downtime. No connections will be terminated and new connections will use the new certificate. The old certificate will only actually be deleted when the new certificate is uploaded and active.

To update a certificate in the dashboard:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. In Edge Certificates, locate a custom certificate and select it to expand.

  3. Select the wrench button and choose Replace SSL certificate and key.

  4. Follow the same steps as upload a new certificate.

To update a certificate using the API, send a PATCH command.

:::note

To update the Private Key Restriction setting of a certificate, you must delete and re-add the certificate — this is an exception to the recommended renewal flow above. Plan for potential downtime if no other certificate covers the same hostnames.

:::


Delete a custom certificate

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. In Edge Certificates, locate a custom certificate and select it to expand.

  3. Select the cross button.

  4. Select Confirm to delete the certificate.

Geo Key Manager

import { CardGrid, Description, DirectoryListing, LinkTitleCard, RelatedProduct, Render, } from "~/components";

Restrict where the private keys used for TLS certificates are stored and managed.

Geo Key Manager allows customers to store and manage the encryption keys for their domains in different geographic locations so they can meet compliance regulations and keep data secure.

Resources

Limitations

Currently, Geo Key Manager is limited to custom certificates and available only through the Cloudflare API.


<RelatedProduct header="Data Localization Suite" href="/data-localization/" product="data-localization"

The Data Localization Suite (DLS) is a set of products that helps customers
who want to maintain local control over their traffic while retaining the
security benefits of a global network.

<RelatedProduct header="Geo Key Manager (v1)" href="https://blog.cloudflare.com/introducing-cloudflare-geo-key-manager/" product="ssl"

{" "}
<Render file="geokey-manager-v1" product="ssl" />

More resources

<LinkTitleCard title="Plans" href="https://www.cloudflare.com/plans/#overview" icon="document"

Compare available Cloudflare plans

Setup

import { Render, TabItem, Tabs, InlineBadge, APIRequest, Example, } from "~/components";

Geo Key Manager v2

:::note

Geo Key Manager v2 is only available through the Cloudflare API.

:::

Geo Key Manager v2 gives customers flexibility when choosing the geographical boundaries of where their keys are stored.

Using the policy field, customers can define policies containing allow and block lists of countries or regions where the private key should be stored.

To use Geo Key Manager v2 with the API, generally, follow the steps to upload a custom certificate.

When sending the POST request, include the policy parameter to define policies containing allow and block lists of countries or regions where the private key should be stored.

:::note

You also have access to the geo_restrictions parameter, which is mutually exclusive with the policy parameter and is part of Geo Key Manager v1.

:::

Examples

Store private keys in the E.U. and the U.S.

<APIRequest path="/zones/{zone_id}/custom_certificates" method="POST" json={{ certificate: "certificate", private_key: "<PRIVATE_KEY>", policy: "(country: US) and (region: EU)", type: "sni_custom", }} />

Store private keys in the E.U., but not in France

<APIRequest path="/zones/{zone_id}/custom_certificates" method="POST" json={{ certificate: "certificate", private_key: "<PRIVATE_KEY>", policy: "(region: EU) and (not country: FR)", type: "sni_custom", }} />

:::note

For more information on the policy field, refer to Supported options.

:::

Geo Key Manager v1

To use Geo Key Manager in the dashboard:

  1. Follow the steps to upload a custom certificate.
  2. For Private Key Restriction, choose one of the following options:
    • Distribute to all Cloudflare data centers (optimal performance)
    • Distribute only to U.S. data centers
    • Distribute only to E.U. data centers
    • Distribute only to highest security data centers (more details)
  3. Select Upload Custom Certificate.

To use Geo Key Manager with the API, generally, follow the steps to upload a custom certificate.

When sending the POST request, include the geo_restrictions parameter set to one of the following options:

Supported options

For customers with Geo Key Manager v2, you can use the policy parameter to specify following regions using the Region code:

Region code Region name
AFR Africa
APAC Asia Pacific
EEUR Eastern Europe
ENAM Eastern North America
EU European Union
ME Middle East
OC Oceania
SAM South America
WEUR Western Europe
WNAM Western North America

Available countries

For customers with Geo Key Manager v2, you can use the policy parameter to specify individual countries as well. Cloudflare is constantly expanding the number of supported countries. To indicate a country, specify the two-letter (ISO 3166) country code.

Examples of supported countries are Japan, Canada, India, and Australia.


Highest security data centers

For customers with both Geo Key Manager v1 and v2, you can use the geo_restrictions parameter to only choose Cloudflare's highest security data centers.

The following aspects are unique to our highest security data centers, but the baseline security requirements for all data centers are also detailed in our blog.

Pre-scheduled and biometric controlled facility access

Employees of Cloudflare permitted to access the facility must have previously scheduled a visit before access will be granted.

Access to the entrance of the facility is controlled through the use of a biometric hand reader combined with an assigned access code.

Private cages with biometric readers

All equipment is in private cages with physical access controlled via biometrics and recorded in audit logs. Entrants have to pass through five separate readers before they can access the cage.

Exterior security controls and monitoring

All points of ingress/egress are monitored by an intrusion detection system (IDS), with authorized users and access events archived for historical review.

Interior security controls and monitoring

Interior points of ingress/egress are controlled by the access control subsystem, with entry routed through a mantrap. All areas are monitored and recorded with closed-circuit television, with data kept for a minimum of thirty days.

Exterior walls are airtight and may incorporate additional security measures such as reinforced concrete, Kevlar bullet board, vapor barriers, or bullet-proof front doors.

Alerts

import { AvailableNotifications, Render } from "~/components"

You can configure alerts to receive notifications for changes in your certificates.

Disable Universal SSL certificates

import { TabItem, Tabs, DashButton } from "~/components";

Some customers may need to manage their own SSL certificates or rely on specific Certificate Authorities.

If you disable your domain's Universal SSL certificate, Cloudflare removes that certificate from our network and will not order or renew any additional Universal SSL certificates.

Disabling Universal SSL will not cause any interruption to ongoing TLS connections to your domain on Cloudflare's network, they will continue to be served according to the Universal SSL certificate used when they were first established. Eventually these connections will naturally end.

New TLS connections are expected to succeed as long as you have another valid certificate active, such as a custom) or advanced certificate. New TLS connections will receive the highest priority certificate from our edge as per our certificate and hostname priority. If a valid certificate is not active before disabling, TLS connections will fail. For more information, refer to Potential errors below.

Potential errors

To avoid errors with your domain, either upload a custom certificate or purchase Advanced Certificate Manager before disabling Universal SSL.

If you disable Universal SSL, you may experience errors with the following scenarios:

Disable Universal SSL certificate

Before you disable Universal SSL/TLS, make sure you have uploaded a custom certificate or purchased Advanced Certificate Manager to protect your domain.

To disable Universal SSL in the dashboard:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. For Disable Universal SSL, select Disable Universal SSL.

  3. Read the warnings in the Acknowledgement.

  4. Select I Understand and select Confirm.

To disable Universal SSL with the Cloudflare API, send a PATCH request and include the "enabled": false parameter.

Re-enable Universal SSL

To re-enable Universal SSL in the dashboard:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. For Disable Universal SSL, select Enable Universal SSL.

To re-enable Universal SSL with the Cloudflare API, send a PATCH request and include the "enabled": true parameter.

Enable Universal SSL certificates

import { GlossaryDefinition, Render } from "~/components";


The process for activating a Universal SSL certificate depends on your domain's DNS setup.

Full DNS setup

Minimize downtime

If your website or application is already live and cannot be uncovered while the Universal certificate is provisioned, consider the following:

:::note If your domain is using a partial setup, you will need to add Domain Control Validation (DCV) records to your authoritative DNS. :::

Partial DNS setup

For non-authoritative or partial domains, Universal SSL will be:

Unless you cover and validate multiple subdomains with an advanced certificate, you will need to proxy and validate new subdomains as they are added.


Verify your certificate is active

Once you enable Universal SSL, you can review the activation status on the Edge Certificates page or via the API with a GET request.


Universal SSL renewal

For details, refer to Validity periods and renewal.

Universal SSL

import { GlossaryDefinition, Render } from "~/components";

On a full setup, Universal SSL certificates cover your root domain (for example, example.com) and first-level subdomains (for example, www.example.com). On a partial (CNAME) setup, each proxied subdomain receives its own certificate regardless of depth. Cloudflare handles issuance, renewal, and deployment automatically.

For full setup zones that need coverage beyond first-level subdomains, use Total TLS or advanced certificates.

Universal certificates are Domain Validated (DV), which means the certificate authority verifies domain ownership but does not validate organization identity. For setup details, refer to Enable Universal SSL.

:::note Universal SSL certificates are issued after your domain is active on Cloudflare. If you need an SSL certificate before migrating traffic, or if you need to customize cipher suites, use Advanced or Custom certificates. :::

Availability

Free Pro Business Enterprise
Availability Yes Yes Yes Yes

Limitations

import { GlossaryTooltip, Render } from "~/components";

Universal SSL certificates present some limitations.

Proxy status

Cloudflare can only serve an SSL/TLS certificate for a DNS record when you set the record's proxy status to Proxied. If you do not do this, the origin server your record points to will be responsible for supporting SSL/TLS connections.

Hostname coverage

Full setup

When you rely only on Universal SSL in a full setup zone, coverage is limited to the root domain (for example, example.com) and first-level subdomains (for example, www.example.com or blog.example.com). Deeper subdomains — such as dev.www.example.com or app3.dev.www.example.com — are not covered and will not serve a valid certificate.

To enable SSL for deeper subdomains, you can:

CNAME setup

On a CNAME setup zone, each subdomain (regardless of level) has its own Universal SSL certificate and does not require additional features or purchases. As long as the subdomains are proxied to Cloudflare, a universal certificate will be provisioned.

Certificate authority

For Universal SSL certificates, Cloudflare chooses the certificate authority (CA) used for your certificate.

Cloudflare can change the certificate authority without prior notification, and will not send any notification as the change happens.

If you want to choose the issuing certificate authority, order an advanced certificate.

Certificate type

The type of certificate included in a Universal SSL certificate pack depends on your zone plan:

When you upgrade your zone from the Free plan to a paid plan, Cloudflare does not automatically re-issue your Universal SSL certificate. Your existing ECDSA-only certificate continues to serve until the certificate pack next renews. At renewal, Cloudflare issues both an RSA and an ECDSA certificate for your zone.

If you need an RSA certificate before the next renewal, order an advanced certificate (requires the Advanced Certificate Manager add-on).

Validity period

For Universal certificates, Cloudflare controls the validity period. Refer to validity periods and renewal for details.

TLS settings

Customizing cipher suites is only available with Advanced Certificate Manager or within Cloudflare for SaaS.

You can set up minimum TLS version at the zone level, but, for per-hostname settings, you must have Advanced Certificate Manager.

Delegated DCV

Delegated DCV allows zones with partial DNS setups to delegate the DCV process to Cloudflare. DCV delegation will not work with Universal SSL certificates and requires the use of an advanced certificate.

Spectrum

Universal SSL is not compatible with Cloudflare Spectrum. If you are trying to use Spectrum, use either an advanced certificate or a custom certificate.

Load balancing

Due to internal limitations, Universal SSL certificates do not cover load balancing hostnames by default. This behavior will be corrected in the future.

Browser support

For more on browser support, see Browser compatibility.

SSL invalid brand check

Some domains are not eligible for Universal SSL if they contain words that conflict with trademarked domains.

To resolve this issue, you can:

Certificate pinning

Troubleshooting

If a certificate issuance times out, Cloudflare tells you where in the chain of issuance the timeout occurred: Initializing, Validation, Issuance, Deployment, or Deletion.

To resolve timeout issues, try one or more of the following options:

Delete certificates

You can use the API to delete certificates that you no longer want listed on the Cloudflare dashboard.

RSA certificate not available after plan upgrade

If you upgraded your zone from Free to a paid plan and your Universal SSL certificate includes only an ECDSA certificate (no RSA certificate), this is expected behavior. Cloudflare does not automatically re-issue the Universal SSL certificate when you change your plan.

Your RSA certificate will be issued when the certificate pack next renews. To get an RSA certificate sooner, you can:

For details, refer to Certificate type.

Other issues

For additional troubleshooting help, refer to Troubleshooting SSL errors.

Glossary

The key server is a daemon that you run on your own infrastructure. The key server receives inbound requests from Cloudflare's keyless client on TCP port 2407 (by default) so you must make sure that your firewall and other access control lists permit these requests from Cloudflare's IP ranges.

Your key servers are contacted by Cloudflare during the TLS handshake process and must be online to terminate new TLS connections. Existing sessions can be resumed using unexpired TLS session tickets without needing to contact the key server.

Cloudflare Keyless SSL client (“keyless client”)

The keyless client is a process that runs on Cloudflare's infrastructure. The keyless client makes outbound requests to your key server on TCP port 2407 for assistance in establishing new TLS sessions.

Keyless SSL

import { Render } from "~/components";


Before configuring Keyless SSL, you should read our technical background on how the technology works and where your infrastructure sits within the scope of the TLS handshake.

The source code for our key server (what you will run) and keyless client (what our servers will contact your key server with) can be found on GitHub.


Availability

Free Pro Business Enterprise
Availability No No No Paid add-on

Keyless SSL is only available to Enterprise customers that maintain their own SSL certificate purchased from a valid Certificate Authority. Cloudflare does not supply any certificates for use with Keyless SSL.


Limitations

TLS 1.3 is supported for Keyless SSL with ECDSA certificates. Keyless SSL connections that use RSA certificates negotiate up to TLS 1.2.

Troubleshooting

To check logs, use a command similar to the following.

Enable debug logging

To enable debug logging, use a command similar to the following.

cd /etc/keyless
sudo -u keyless gokeyless --loglevel 0

When running in a container, gokeyless is the container's main process (PID 1), so the host/systemd command above does not apply. Instead, set the log level when you start the container and read logs from the container runtime:

# Set verbosity via environment variable
docker run ... -e KEYLESS_LOGLEVEL=0 ghcr.io/cloudflare/gokeyless:latest

# Read logs
docker logs -f <CONTAINER>   # or: kubectl logs -f <POD>

Browsers are seeing a TLS connection failure after trying to connect

  1. Make sure your key server is accessible from outside your network (tcp/2407).
  2. Provide a packet capture: sudo tcpdump -nni <interface> -s 0 -w keyless-$(date +%s).pcap port 2407

Clients are connecting, but immediately aborting

If you run gokeyless with debug logging enabled, and you see logs like this:

[DEBUG] connection 162.158.57.220:37490: reading half closed by client
[DEBUG] connection 162.158.57.220:37490: server closing connection
[DEBUG] connection 162.158.57.220:37490 removed
[DEBUG] spawning new connection: 162.158.57.220:37862
[DEBUG] connection 162.158.57.220:37862: reading half closed by client
[DEBUG] connection 162.158.57.220:37862: server closing connection
[DEBUG] connection 162.158.57.220:37862 removed

These logs likely indicate that the key server is not using an appropriate server or .PEM file and the client is aborting the connection after the certificate exchange. The certificate must be signed by the keyless CA and the SANs must include the hostname of the keyless server. Here is a valid example for a keyless server located at 11aa40b4a5db06d4889e48e2f.example.com (note the Subject Alternative Name and Authority Key Identifier):

openssl x509 -in server.pem -noout -text -certopt no_subject,no_header,no_version,no_serial,no_signame,no_validity,no_subject,no_issuer,no_pubkey,no_sigdump,no_aux | sed -e 's/^        //'
X509v3 extensions:
    X509v3 Key Usage: critical
        Digital Signature, Key Encipherment
    X509v3 Extended Key Usage:
        TLS Web Server Authentication
    X509v3 Basic Constraints: critical
        CA:FALSE
    X509v3 Subject Key Identifier:
        DD:24:97:F1:A9:F1:4C:73:D9:1B:44:EC:A1:C3:10:E9:F0:41:98:BB
    X509v3 Authority Key Identifier:
        keyid:29:CE:8F:F1:9D:4C:BA:DE:55:78:D7:A6:29:E9:C5:FD:1D:9D:21:48

    X509v3 Subject Alternative Name:
        DNS:11aa40b4a5db06d4889e48e2f.example.com
    X509v3 CRL Distribution Points:

        Full Name:
          URI:http://ca.cfdata.org/api/v1/crl/key_server

The gokeyless binary cannot load the CA file

Ensure permissions are correct on all keys and certificates installed on the server.

Keyless is affecting to unanticipated hosts

You will need to either provide a certificate for only those hosts or change the priority of the certificate in the SSL/TLS app of your Cloudflare dashboard.

Key servers on Windows

Cloudflare currently only provide packages for the supported GNU/Linux distributions as per the Cloudflare package repository.

However, the key server is open source so you may attempt to build and deploy a binary, but running on Windows is not a supported configuration so you may experience problems that Cloudflare will not be able to help with.

Key server multi-domain support

A single key server can serve multiple domains. Add each certificate's private key to the private_key_stores block in gokeyless.yaml, or pass them with --private-key-dirs / --private-key-files. Refer to Serve multiple private keys for details.

The hostname and zone_id fields are single string values used only during enrollment. You do not need to update them for additional domains.

Additional questions

Contact your account team or Cloudflare Support.

Upgrade your key server

Periodically, you may need to update your key server when using Cloudflare's Keyless SSL.

To upgrade your key server:

  1. Back up the contents of /etc/keyless.
  2. Update your OS’ package listings, for example, apt-get update or yum update.
  3. Upgrade the gokeyless server:
  4. Debian/Ubuntu: apt-get upgrade gokeyless
  5. RHEL/CentOS: yum install gokeyless
  6. Restart the keyless instance:
  7. systemd: service gokeyless restart
  8. upstart/sysvinit: /etc/init.d/gokeyless restart
  9. Confirm that HTTPS connections are working as expected.

:::caution

If you are running a high availability configuration, upgrade one server at a time as new TLS connections will fail to terminate at Cloudflare's global network without a functioning key server.

:::

Cloudflare Tunnel

import { Render } from "~/components";

Through an integration with Cloudflare Tunnel, you can send traffic to a key server through a secure channel and avoid exposing your key server to the public Internet.



1. Install cloudflared on key server

First, install cloudflared on your key server.

2. Create a tunnel and add a route

Then, create a Cloudflare Tunnel.

During tunnel creation, go to the CIDR tab and enter the private IP address of your key server. You can also add a CIDR route after creating the tunnel.

After you create the tunnel, use the Cloudflare API to List tunnel routes, saving the following values for a future step:

3. Upload Keyless SSL Certificates

To upload a Keyless certificate with the API, send a POST request that includes a "tunnel" object.

"tunnel": {
  "vnet_id": "<VIRTUAL_NETWORK_ID>",
  "private_ip": "<NETWORK>"
}

:::note

When you receive the network value from the Tunnel route API, it will include a subnet mask, such as 10.0.0.1/32. Remove the subnet mask and use the IP address (10.0.0.1).

:::

4. Set up and activate key server

<Render file="keyless-key-server-setup" product="ssl" params={{ one: "keyserver.keyless.example.com" }} />

Get started

import { DirectoryListing } from "~/components"

The way you set up Keyless SSL depends on how you route traffic to your keyless server.

Public DNS

import { Render, TabItem, Tabs, DashButton } from "~/components";

If you cannot use a Cloudflare Tunnel setup, you can also create a public DNS record for your key server.

This setup option is not ideal as the DNS record cannot be proxied and - as a result - will expose the origin IP address of your key server.



1. Create public DNS record

  1. Open a Terminal and run openssl rand -hex 24 to generate a long, random hostname such as 11aa40b4a5db06d4889e48e2f738950ddfa50b7349d09b5f.example.com.
  2. Add this record via your DNS provider’s interface as an A or AAAA record pointing to the IP address of your Keyless SSL server.
  3. Use this hostname as the server hostname during initialization of your Keyless SSL server.

:::caution

As a security measure, you should hide the hostname of your key server.

:::

:::note

If your key server hostname is on a Cloudflare zone, you must create a DNS-only (grey cloud) record for it — do not proxy it. If the record is proxied, the hostname resolves to Cloudflare's edge IP addresses instead of your key server, so Cloudflare's keyless client cannot reach it. If the record is missing, resolution fails with NXDOMAIN. Either way, the Keyless SSL handshake fails. The fix is the DNS-only record — not adding the hostname to a certificate Subject Alternative Name (SAN).

:::


Certificates used in Keyless SSL

Keyless SSL involves two different certificates. Confusing them is the most common setup error.

Certificate What it is SAN should contain
Edge (Keyless SSL) certificate The public certificate Cloudflare serves for your site. Your site hostnames only (for example, www.example.com)
Key server authentication certificate The certificate your key server uses to prove itself to Cloudflare. The key server hostname only

:::caution

Do not add your key server hostname to the SAN of your public edge certificate. It is not required, and it leaks internal hostnames into the public certificate and Certificate Transparency logs.

:::


2. Upload Keyless SSL Certificates

To create a Keyless certificate in the dashboard:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. Select Upload Keyless SSL Certificate.

  3. Fill in the upload modal with the certificate and other details and select Add.

Label Description Example Values
Key server label Any unique identifier for your key server. “test-keyless”, “production-keyless-1”
Key server hostname The hostname of your key server that holds the key for this certificate (such as the random hostname generated earlier). 11aa40b4a5db06d4889e48e2f738950ddfa50b7349d09b5f.example.com
Key server port Set to 2407 unless you have changed this on the key server. 2407
SSL Certificate The valid X509v3 SSL certificate (in PEM form) for which you hold the private key. (PEM bytes)
Bundle method This should almost always be Compatible. Refer to Uploading Custom Certificates for more details. Compatible

To create a Keyless certificate with the API, send a POST request.


3. Set up and activate key server

<Render file="keyless-key-server-setup" product="ssl" params={{ one: "11aa40b4a5db06d4889e48e2f.example.com" }} />

Allow incoming connections from Cloudflare

During TLS handshakes, Cloudflare's keyless client will initiate connections to the key server hostname or IP address you specify during certificate upload. By default, the keyless client will use a destination TCP port of 2407, but this can be changed during certificate upload or by editing the certificate details after upload.

Create WAF custom rules that allow your key server to accept connections from only Cloudflare. You can get Cloudflare's IPv4 and IPv6 addresses via the IP details API endpoint.

Run with Docker

The gokeyless key server is published as a container image, and most settings can be configured with environment variables instead of a gokeyless.yaml file.

Pull the image

docker pull ghcr.io/cloudflare/gokeyless:latest

:::note The image is published on the GitHub Container Registry (ghcr.io), not Docker Hub. :::

A complete example is available in docker-compose.example.yaml in the gokeyless repository.

Environment variables

Each environment variable maps to the equivalent setting in gokeyless.yaml. When both are present, the environment variable takes precedence (the order is command-line flag, then environment variable, then configuration file).

Environment variable Purpose
KEYLESS_HOSTNAME Hostname of this key server (must match the value configured in Cloudflare).
KEYLESS_ZONE_ID Cloudflare Zone ID.
KEYLESS_ORIGIN_CA_API_KEY Origin CA API key used to enroll the key server and obtain its authentication certificate.
KEYLESS_AUTH_CERT Path to the key server authentication certificate (default server.pem).
KEYLESS_AUTH_KEY Path to the authentication certificate private key (default server-key.pem).
KEYLESS_AUTH_CSR Path to write the CSR generated during initialization (default server.csr).
KEYLESS_CLOUDFLARE_CA_CERT Path to the Cloudflare CA certificate used to authenticate connecting key clients (default keyless_cacert.pem).
KEYLESS_PORT Port the key server listens on (default 2407).
KEYLESS_METRICS_PORT Port for the /metrics endpoint (default 2406).
KEYLESS_LOGLEVEL Log verbosity, 0 (most verbose) to 5.

Configure private keys

Private key locations cannot be set with an environment variable. Configure them with a private_key_stores block in gokeyless.yaml (each entry sets exactly one of dir, file, or uri), or with the --private-key-dirs / --private-key-files flags (comma-separated), passed as arguments after the image name.

Run the container

docker run -d \
  -e KEYLESS_HOSTNAME=<KEY_SERVER_HOSTNAME> \
  -e KEYLESS_ZONE_ID=<ZONE_ID> \
  -e KEYLESS_AUTH_CERT=/config/server.pem \
  -e KEYLESS_AUTH_KEY=/config/server-key.pem \
  -e KEYLESS_CLOUDFLARE_CA_CERT=/config/keyless_cacert.pem \
  -v /local/config:/config:ro \
  -v /local/keys:/keys:ro \
  -p 2407:2407 \
  ghcr.io/cloudflare/gokeyless:latest \
  --private-key-dirs /keys

The image entrypoint is gokeyless, so any command-line flags (such as --private-key-dirs) are appended after the image name.

Serve multiple private keys

A single key server can hold private keys for multiple certificates. List several directories or files with --private-key-dirs / --private-key-files (comma-separated), or define multiple private_key_stores entries in gokeyless.yaml.

AWS cloud HSM

:::note[Note]

This example imports an existing key pair, but you may prefer to generate your key on the HSM.

:::


Before you start

Make sure you have:


1. Import the public and private key to the HSM

Before importing the public key, extract it from the certificate provided by your CA. Place the contents of your private key in privkey.pem and then run the following (replacing certificate.pem with your actual certificate) to populate pubkey.pm.

keyserver$ openssl x509 -pubkey -noout -in certificate.pem > pubkey.pem

Log in to the CloudHSM using a previously created crypto user (CU) account and generate a key encryption key that will be used to import your private key.

keyserver$ /opt/cloudhsm/bin/key_mgmt_util
Command: loginHSM -u CU -s patrick -p donahue
Command: genSymKey -t 31 -s 16 -sess -l import-wrapping-key
...
Symmetric Key Created.  Key Handle: 658
...

Referencing the key handle returned above, import the private and public key and then log out of the HSM:

Command: importPrivateKey -f privkey.pem -l mykey -id 1 -w 658
...
Cfm3WrapHostKey returned: 0x00 : HSM Return: SUCCESS
Cfm3CreateUnwrapTemplate returned: 0x00 : HSM Return: SUCCESS
Cfm3UnWrapKey returned: 0x00 : HSM Return: SUCCESS
...
Private Key Unwrapped.  Key Handle: 658


Command: importPubKey -f pubkey.pem -l mykey -id 1
Cfm3CreatePublicKey returned: 0x00 : HSM Return: SUCCESS
...
Public Key Handle: 941


Command: logoutHSM
Command: exit

2. Modify the gokeyless config file and restart the service

Now that the keys are in place, we need to modify the configuration file that the key server will read on startup. Change the object=mykey and pin-value=username:password values to match the key label you provided and CU user you created.

Open /etc/keyless/gokeyless.yaml and immediately after:

private_key_stores:
  - dir: /etc/keyless/keys

add:

- uri: pkcs11:token=cavium;object=mykey?module-path=/opt/cloudhsm/lib/libcloudhsm_pkcs11_standard.so&pin-value=patrick:donahue&max-sessions=1

With the config file saved, restart gokeyless and verify it started successfully.

sudo systemctl restart gokeyless.service
sudo systemctl status gokeyless.service -l

Azure Dedicated HSM

This tutorial uses Azure Dedicated HSM — a FIPS 140-2 Level 3 certified implementation based on the Gemalto SafeNet Luna a790.


Before you start

Make sure you have:


1. Create, assign, and initialize a new partition

The first step is creating an HSM partition, which can be thought of as an independent logical HSM within your Azure Dedicated HSM device.

vm$ ssh tenantadmin@hsm

[local_host] lunash:>hsm login
  Please enter the HSM Administrators' password:
  > ********


'hsm login' successful.


Command Result : 0 (Success)

[local_host] lunash:>partition create -partition KeylessSSL


          Type 'proceed' to create the partition, or
          'quit' to quit now.
          > proceed
'partition create' successful.


Command Result : 0 (Success)

Next, the partition needs to be assigned to the client, in this case your key server.

[local_host] lunash:>client assignpartition -client azure-keyless -partition KeylessSSL


'client assignPartition' successful.


Command Result : 0 (Success)

After the partition has been assigned, run lunacm from your virtual server and initialize the partition.

vm$ lunacm
lunacm (64-bit) v7.2.0-220. Copyright (c) 2018 SafeNet. All rights reserved.


  Available HSMs:

  Slot Id ->              0
  Label ->
  Serial Number ->        XXXXXXXXXXXXX
  Model ->                LunaSA 7.2.0
  Firmware Version ->     7.0.3
  Configuration ->        Luna User Partition With SO (PW) Signing With Cloning Mode
  Slot Description ->     Net Token Slot


  Current Slot Id: 0

lunacm:>partition init -label KeylessSSL -domain cloudflare

  Enter password for Partition SO: ********

  Re-enter password for Partition SO: ********

  You are about to initialize the partition.
  All contents of the partition will be destroyed.

  Are you sure you wish to continue?

  Type 'proceed' to continue, or 'quit' to quit now ->proceed

Command Result : No Error

2. Generate a RSA key pair and certificate signing request (CSR)

Before running the commands below, check with your information security and/or cryptography team to confirm the approved key creation procedures for your organization.

# cmu generatekeypair -keyType=RSA -modulusBits=2048 -publicExponent=65537 -sign=1 -verify=1 -labelpublic=myrsakey -labelprivate=myrsakey -keygenmech=1

Please enter password for token in slot 0 : ********

# cmu list

Please enter password for token in slot 0 : ********
handle=51 label=myrsakey
handle=48 label=myrsakey

Using the key created in the previous step, generate a CSR that can be sent to a publicly trusted Certificate Authority (CA) for signing.

# cmu requestCertificate -c="US" -o="Example, Inc." -cn="azure-dedicatedhsm.example.com" -s="California" -l="San Francisco" -publichandle=48 -privatehandle=51 -outputfile="rsa.csr" -sha256withrsa

Please enter password for token in slot 0 : ********
Using "CKM_SHA256_RSA_PKCS" Mechanism

3. Obtain and upload a signed certificate from your Certificate Authority (CA)

Provide the CSR created in the previous step to your organization's preferred CA, demonstrate control of your domain as requested, and then download the signed SSL certificates. Follow the instructions provided in Upload Keyless SSL Certificates.


4. Modify your gokeyless config file and restart the service

Lastly, we need to modify the configuration file that the key server will read on startup. Be sure to change the object=mykey and pin-value=username:password values to match the key label you provided and CU user you created.

Open /etc/keyless/gokeyless.yaml and immediately after:

private_key_stores:
  - dir: /etc/keyless/keys

add:

- uri: pkcs11:token=KeylessSSL;object=myrsakey?module-path=/usr/safenet/lunaclient/lib/libCryptoki2_64.so&pin-value=password&max-sessions=1

With the config file saved, restart gokeyless and verify it started successfully.

sudo systemctl restart gokeyless.service
sudo systemctl status gokeyless.service -l

Azure Managed HSM

This tutorial uses Microsoft Azure’s Managed HSM — a FIPS 140-2 Level 3 certified implementation — to deploy a VM with the Keyless SSL daemon.


Before you start

Make sure you have:


1. Create a VM

Create a VM where you will deploy the keyless daemon.


2. Deploy the keyless server

Follow these instructions to deploy your keyless server.


3. Set up the Azure CLI

Set up the Azure CLI (used to access the private key).

For example, if you were using macOS:

brew install azure-cli

4. Set up the Managed HSM

  1. Log in through the Azure CLI and create a resource group for the Managed HSM in one of the supported regions:

    az login
    az group create --name HSMgroup --location southcentralus
    

    :::note For a list of supported regions, see the Microsoft documentation. :::

  2. Create, provision, and activate the HSM.

  3. Add your private key to the keyvault, which returns the URI you need for Step 4:

    az keyvault key import --hsm-name "KeylessHSM" --name "hsm-pub-keyless" --pem-file server.key
    
  4. If the key server is running in an Azure VM in the same account, use Managed services for authorization:

    1. Enable managed services on the VM in the UI.

    2. Give your service user (associated with your VM) HSM sign permissions

      az keyvault role assignment create  --hsm-name KeylessHSM --assignee $(az vm identity show --name "hsmtestvm" --resource-group "HSMgroup" --query principalId -o tsv) --scope / --role "Managed HSM Crypto User"
      
  5. In the gokeyless YAML file, add the URI from Step 2 under private_key_stores. See our README for an example.

5. Restart gokeyless

Once you save the config file, restart gokeyless and verify that it started successfully:

sudo systemctl restart gokeyless.service
sudo systemctl status gokeyless.service -l

Configuration

:::caution[Important]

Carefully review the manufacturer documentation for your HSM and properly restrict access to the key server.

:::

To get started with your PKCS#11 token you will need to initialize it with a private key, PIN, and token label. The instructions to do this will be specific to each hardware device, and you should follow the instructions provided by your vendor. You will also need to find the path to your module, a shared object file (.so). Having initialized your device, you can query it to check your token label with:

pkcs11-tool --module <module path> --list-token-slots

You will also want to check the label of the private key you imported (or generated). Run the following command and look for a Private Key Object:

pkcs11-tool --module <module path> --pin <pin> \
    --list-token-slots --login --list-objects

You now have all the information you need to use your PKCS#11 token with the Keyless server, by adding to the private_key_stores section in the configuration file. You can specify the key pairs that you want Keyless to have access to in the configuration file using the PKCS#11 URI format.

PKCS#11 URI

A PKCS#11 URI is a sequence of attribute value pairs separated by a semicolon that form a one-level path component, optionally followed by a query. The general form represented is:

pkcs11:path-component[?query-component]

The URI path component contains attributes that identify a resource. The query component can contain a few attributes that may be needed to retrieve the resource identified by the URI path component. Attributes in the path component are delimited by the ; character, and attributes in the query component use & as a delimiter. All attributes are URL-encoded.

Keyless requires the following three attributes be specified:

For certain modules, a query attribute max-sessions is required in order to prevent opening too many sessions to the module. Certain additional attributes, such as pin-value, may be necessary depending on the situation. Refer to the documentation for your PKCS#11 module for more details.

Examples

Here are some examples of PKCS#11 URIs for keys stored on various modules:

private_key_stores:
- uri: pkcs11:token=SoftHSM2%20RSA%20Token;id=%03?module-path=/usr/lib64/libsofthsm2.so&pin-value=1234
- uri: pkcs11:token=accelerator;object=thaleskey?module-path=/opt/nfast/toolkits/pkcs11/libcknfast.so
- uri: pkcs11:token=YubiKey%20PIV;id=%00?module-path=/usr/lib64/libykcs11.so&pin-value=123456&max-sessions=1
- uri: pkcs11:token=elab2parN;id=%04?module-path=/usr/lib/libCryptoki2_64.so&pin-value=crypto1

Limitations

For now, only one PKCS#11 module can be used at a time, so if you have keys on multiple HSMs, we recommend using p11-glue to consolidate access through one module.

Entrust nShield Connect

:::note[Note]

This example assumes you have already configured the nShield Connect device and generated or imported your private keys.

:::

Since the keys are already in place, we merely need to build the configuration file that the key server will read on startup. In this example the device contains a single RSA key pair.

We ask pkcs11-tool (provided by the opensc package) to display the objects stored in the token:

pkcs11-tool --module /opt/nfast/toolkits/pkcs11/libcknfast.so -O
Using slot 0 with a present token (0x1d622495)
Private Key Object; RSA
  label:      rsa-privkey
  ID:         105013281578de42ea45f5bfac46d302fb006687
  Usage:      decrypt, sign, unwrap
warning: PKCS11 function C_GetAttributeValue(ALWAYS_AUTHENTICATE) failed: rv = CKR_ATTRIBUTE_TYPE_INVALID (0x12)

Public Key Object; RSA 2048 bits
  label:      rsa-privkey
  ID:         105013281578de42ea45f5bfac46d302fb006687
  Usage:      encrypt, verify, wrap

The key piece of information is the label of the object, rsa-privkey. Open up /etc/keyless/gokeyless.yaml and immediately after

private_key_stores:
  - dir: /etc/keyless/keys

add

- uri: pkcs11:token=accelerator;object=rsa-privkey?module-path=/opt/nfast/toolkits/pkcs11/libcknfast.so&max-sessions=4

Save the config file, restart gokeyless, and verify it started successfully.

sudo systemctl restart gokeyless.service
sudo systemctl status gokeyless.service -l

Fortanix Data Security Manager

import { Example } from "~/components";

You can use Cloudflare Keyless SSL with Fortanix Data Security Manager (DSM), a FIPS 140-2 Level 3 certified implementation.

You must have a Data Security Manager Enterprise Tier and set up a group and an application assigned to the group.

For detailed guidance, follow the tutorial in the Fortanix documentation. This guide is based on the Keyless SSL public DNS option and has been tested using a virtual machine (VM) deployed to Azure running Ubuntu 22.04.3 LTS.

Google Cloud HSM

This tutorial uses Google Cloud HSM — a FIPS 140-2 Level 3 certified implementation.


Before you start

Make sure that you have:


1. Create a key ring

To set up the Google Cloud HSM, create a key ring and indicate its location.

:::note[Note:]

Only certain locations support Google Cloud HSM.

:::


2. Create a key

Create a key, including the following information:

Field Value
Key ring The key ring you created in Step 2
Protection level HSM
Purpose Asymmetric Encrypt

3. Import the private key

After creating a key ring and key, import the private key.

:::note[Note:]

You need to convert your key from a PEM to DER format.

:::


4. Modify your gokeyless config file and restart the service

Once you’ve imported the key, copy the Resource name from the UI. Then, add this value to the gokeyless YAML file under private_key_stores.

With the config file saved, restart gokeyless and verify it started successfully.

sudo systemctl restart gokeyless.service
sudo systemctl status gokeyless.service -l

IBM Cloud HSM

The example below was tested using IBM Cloud HSM 7.0, a FIPS 140-2 Level 3 certified implementation based on the Gemalto SafeNet Luna a750.


Before you start

Make sure that you have:


1. Create, assign, and initialize a new partition

The first step is creating an HSM partition, which can be thought of as an independent logical HSM within your IBM Cloud HSM device.

vm$ ssh admin@hsm

[cloudflare-hsm.softlayer.com] lunash:>partition create -partition KeylessSSL


          Type 'proceed' to create the partition, or
          'quit' to quit now.
          > proceed
'partition create' successful.


Command Result : 0 (Success)

Next, the partition needs to be assigned to the client, in this case your key server.

[cloudflare-hsm.softlayer.com] lunash:>client assignpartition -client cloudflare-vm.softlayer.com -partition KeylessSSL


'client assignPartition' successful.


Command Result : 0 (Success)

After the partition has been assigned, run lunacm from your virtual server and initialize the partition.

vm$ lunacm
LunaCM v7.1.0-379. Copyright (c) 2006-2017 SafeNet.

    Available HSMs:

    Slot Id ->              0
    Label ->
    Serial Number ->        XXXXXXXXXXXXX
    Model ->                LunaSA 7.0.0
    Firmware Version ->     7.0.1
    Configuration ->        Luna User Partition With SO (PW) Signing With Cloning Mode
    Slot Description ->     Net Token Slot


    Current Slot Id: 0

lunacm:>partition init -label KeylessSSL -domain cloudflare

  Enter password for Partition SO: ********

  Re-enter password for Partition SO: ********

  You are about to initialize the partition.
  All contents of the partition will be destroyed.

  Are you sure you wish to continue?

  Type 'proceed' to continue, or 'quit' to quit now ->proceed

Command Result : No Error

2. Generate RSA and ECDSA key pairs and certificate signing requests (CSRs)

Before running the commands below, check with your information security and/or cryptography team to confirm the approved key creation procedures for your organization.

When you perform this operation, you need define the ID field for the newly generated keys. It must be set to a big-endian hexadecimal integer value.

vm$ cmu generatekeypair -keyType=RSA -modulusBits=2048 -publicExponent=65537 -sign=1 -verify=1 -labelpublic=myrsakey -labelprivate=myrsakey -keygenmech=1  -id=a000
Please enter password for token in slot 0 : ********

# cmu generatekeypair -keyType=ECDSA -curvetype=3 -sign=1 -verify=1 -labelpublic=myecdsakey -labelprivate=myecdsakey -id=a001
Please enter password for token in slot 0 : ********

# cmu list
Please enter password for token in slot 0 : ********
handle=61   label=myecdsakey
handle=60   label=myecdsakey
handle=48   label=myrsakey
handle=45   label=myrsakey

Using the keys created in the previous step, generate CSRs that can be sent to a publicly trusted Certificate Authority (CA) for signing.

# cmu requestCertificate -c="US" -o="Example, Inc." -cn="ibm-cloudhsm.example.com" -s="California" -l="San Francisco" -publichandle=45 -privatehandle=48 -outputfile="rsa.csr" -sha256withrsa
Please enter password for token in slot 0 : ********
Using "CKM_SHA256_RSA_PKCS" Mechanism

# cmu requestCertificate -c="US" -o="Example, Inc." -cn="ibm-cloudhsm.example.com" -s="California" -l="San Francisco" -publichandle=60 -privatehandle=61 -outputfile="ecdsa.csr" -sha256withecdsa
Please enter password for token in slot 0 : ********
Using "CKM_ECDSA_SHA256" Mechanism

3. Obtain and upload signed certificates from your Certificate Authority (CA)

Provide the CSRs created in the previous step to your organization's preferred CA, demonstrate control of your domain as requested, and then download the signed SSL certificates. Follow the instructions provided in Upload Keyless SSL Certificates.


4. Modify your gokeyless config file and restart the service

Lastly, we need to modify the configuration file that the key server will read on startup. Change the object=mykey and pin-value=username:password values to match the key label you provided and CU user you created.

Open /etc/keyless/gokeyless.yaml and immediately after:

private_key_stores:
  - dir: /etc/keyless/keys

add:

- uri: pkcs11:token=KeylessSSL;object=myrsakeyid=a000??module-path=/usr/safenet/lunaclient/lib/libCryptoki2_64.so&pin-value=password&max-sessions=1
- uri: pkcs11:token=KeylessSSL;object=myecdsakeyid=a001??module-path=/usr/safenet/lunaclient/lib/libCryptoki2_64.so&pin-value=password&max-sessions=1

With the config file saved, restart gokeyless and verify it started successfully.

sudo systemctl restart gokeyless.service
sudo systemctl status gokeyless.service -l

Hardware security modules

In addition to private keys stored on disk, Keyless SSL supports keys stored in a Hardware Security Module (HSM) via the PKCS#11 standard. Keyless uses PKCS#11 for signing and decrypting payloads without having direct access to the private keys.


Why use Keyless SSL with an HSM?

Hardware Security Modules (HSMs) facilitate a higher level of protection for your private keys over storing them directly on your key server. The primary responsibility of an HSM is safeguarding private keys and performing operations such as signing or encryption internally. In addition to access control, that means the physical device must offer some degree of tamper-resistance in order to be compliant with government or industry regulations such as FIPS 140.

Moreover, many HSMs are also capable of generating keys and producing cryptographically secure randomness. Some are purpose-built to perform cryptographic computations more efficiently.


Communicating using PKCS#11

The key server communicates with HSMs via PKCS#11, so any HSM supporting the standard can be used with Keyless SSL.

Initial configuration

For more details on initializing your PKCS#11 token, refer to Configuration.

Compatibility

Keyless SSL has interoperability with the following modules:

Also, the following cloud HSM offerings have been tested with Keyless SSL:

SoftHSMv2

:::caution[Important]

SoftHSMv2 should not be considered any more secure than storing private keys directly on disk. No attempt is made below to secure this installation; it is provided simply for demonstration purposes.

:::


1. Install and configure SoftHSMv2

First, we install SoftHSMv2 and configure it to store tokens in the default location /var/lib/softhsm/tokens. We also need to give the softhsm group permission to this directory as this is how the keyless user will access this directory.

sudo apt-get install -y softhsm2 opensc

#...

cat <<EOF | sudo tee /etc/softhsm/softhsm2.conf
directories.tokendir = /var/lib/softhsm/tokens
objectstore.backend = file
log.level = DEBUG
slots.removable = false
EOF

sudo mkdir /var/lib/softhsm/tokens
sudo chown root:softhsm $_
sudo chmod 0770 /var/lib/softhsm/tokens
sudo usermod -G softhsm keyless
sudo usermod -G softhsm $(whoami)

echo 'export SOFTHSM2_CONF=/etc/softhsm/softhsm2.conf' | tee -a ~/.profile
source ~/.profile

2. Create a token and private keys, and generate CSRs

Next, we create a token in slot 0 called test-token and secure it with a PIN of 1234. In this slot we’ll store the RSA keys for our SSL certificates for keyless-softhsm.example.com.

sudo -u keyless softhsm2-util --init-token --slot 0 --label test-token --pin 1234 --so-pin 4321
The token has been initialized.

Using cfssl, we generate the private keys and Certificate Signing Requests (CSRs), the latter of which will be sent to a Certificate Authority (CA) for signing.

cat <<EOF | tee csr.json
{
    "hosts": [
        "keyless-softhsm.example.com"
    ],
    "CN": "keyless-softhsm.example.com",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [{
        "C": "US",
        "L": "San Francisco",
        "O": "TLS Fun",
        "OU": "Technical Operations",
        "ST": "California"
    }]
}
EOF

cfssl genkey csr.json | cfssljson -bare certificate
2018/08/12 00:52:22 [INFO] generate received request
2018/08/12 00:52:22 [INFO] received CSR
2018/08/12 00:52:22 [INFO] generating key: rsa-2048
2018/08/12 00:52:22 [INFO] encoded CSR

3. Convert and import the key

Now that the key has been generated, it’s time to load it into the slot we created. Before doing so, we need to convert from PKCS#1 to PKCS#8 format. During import, we specify the token and PIN from token initialization and provide a unique hexadecimal ID and label to the key.

openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in certificate-key.pem -out certificate-key.p8
sudo chown keyless certificate-key.p8

sudo -u keyless softhsm2-util --pin 1234 --import ./certificate-key.p8 --token test-token --id a000 --label rsa-privkey
Found slot 915669571 with matching token label.
The key pair has been imported.

After importing we ask pkcs11-tool to confirm the objects have been successfully stored in the token.

sudo -u keyless pkcs11-tool --module /usr/lib/softhsm/libsofthsm2.so -l -p 1234 --token test-token --list-objects
Public Key Object; RSA 2048 bits
  label:      rsa-privkey
  ID:         a000
  Usage:      verify
Private Key Object; RSA
  label:      rsa-privkey
  ID:         a000
  Usage:      sign

4. Modify your gokeyless config file and restart the service

With the keys in place, it’s time to build the configuration file that the key server will read on startup. The id refers to the hexadecimal ID you provided to the softhsm2-util import statement; we used a000 so it is encoded as %a0%00. The module-path will vary slightly based on the Linux distribution you are using. On Debian it should be /usr/lib/softhsm/libsofthsm2.so.

Open up /etc/keyless/gokeyless.yaml and immediately after

private_key_stores:
  - dir: /etc/keyless/keys

add

- uri: pkcs11:token=test-token;id=%a0%00?module-path=/usr/lib/softhsm/libsofthsm2.so&pin-value=1234&max-sessions=1

Save the config file, restart gokeyless, and verify it started successfully.

sudo systemctl restart gokeyless.service
sudo systemctl status gokeyless.service -l

High availability

The Cloudflare Keyless SSL server runs as a single binary with minimal dependencies and is designed to be robust and reliable. However, the network between your key server and Cloudflare may not be, which could prevent new TLS connections.

For this reason, we strongly recommend that you run at least two key servers in a high availability configuration behind a load balancer. Set up health checks for each key server on the configured TCP port—2407 by default and failover as necessary or round-robin between active (healthy) key servers.

From a network availability and performance perspective, advertise the IP address of your key server from multiple data centers (an anycast setup) so the Cloudflare global network can route to the closest key server via BGP. When you use anycast routing, you can also safely take a data center offline to perform maintenance.

Reference

import { DirectoryListing } from "~/components"

For more information on Keyless SSL, refer to the following resources:

Keyless delegation

Keyless Delegation is Cloudflare's implementation of the emerging delegated credentials standard (RFC 9345). When you upload a certificate for use with Keyless that has the special extension permitting the use of delegated credentials, Cloudflare will automatically produce a delegated credential and use it at the edge with clients that support this feature. The handshakes will complete without the extra latency induced by reaching back to the Keyless Server, and there are additional advantages to flexibility in algorithm choice.

Behind the scenes we periodically create delegated credentials and sign them via Keyless, through the same mechanism used to sign the Certificate Verify messages our servers send when using Keyless. These credentials have a short lifetime, ensuring that if you disable Keyless the credentials created will become invalid within 24 hours. Supporting clients validate the credential, and the server can use the key it generated to sign the response to the TLS handshake without the round trip.

For security reasons certificates must contain a special identifier for use with delegated credentials. This takes the form of an optional X509 extension with NULL contents and the OID 1.3.6.1.4.1.44363.44. Your CA may need to make code changes to support delegated credentials.

Currently very few clients support delegated credentials, and only a handful of certificate authorities will issue certificates with the extension. We have had success with DigiCert. Firefox 77 and later support delegated credentials.

Key server metrics

The gokeyless key server exposes a Prometheus metrics endpoint that you can use to monitor signing performance, error rates, connection health, and certificate expiry. This endpoint can also be scraped by the OpenTelemetry Collector Prometheus receiver, making the metrics available to any OpenTelemetry-compatible backend.

Metrics endpoint

By default, metrics are served at:

http://<host>:2406/metrics

The port is configurable via the metrics_port key in your configuration file, the --metrics-port flag, or the KEYLESS_METRICS_PORT environment variable.

The endpoint serves only /metrics. There are no additional HTTP endpoints such as /health or /debug.


Histogram buckets

All histogram metrics share the same bucket configuration: 15 exponential buckets starting at 100 microseconds, doubling each step up to approximately 1.64 seconds, plus a final +Inf bucket.

Bucket Upper bound
1 100 µs
2 200 µs
3 400 µs
4 800 µs
5 1.6 ms
6 3.2 ms
7 6.4 ms
8 12.8 ms
9 25.6 ms
10 51.2 ms
11 102 ms
12 205 ms
13 410 ms
14 819 ms
15 ~1.64 s
+Inf Anything above ~1.64 s

:::note When using a hardware security module (HSM) with a PKCS#11 session pool, the pool wait timeout is hardcoded at 10 seconds. A pool exhaustion event will therefore always appear in the +Inf bucket. Spikes in +Inf observations on signing operations with error="cryptography error" are a direct indicator of PKCS#11 session pool saturation. :::


Metrics reference

keyless_requests

Type: Counter
Labels: opcode

Counts every incoming request received over an established connection, regardless of outcome. Incremented once per request before any processing begins.

The opcode label uses the full constant name from the gokeyless protocol.

RSA operations

opcode label Wire value Description
OpRSADecrypt 0x01 RSA raw decryption — used in TLS RSA key exchange (deprecated in TLS 1.3)
OpRSASignMD5SHA1 0x02 RSA PKCS#1 v1.5 signature over MD5+SHA1 combined hash — TLS 1.0/1.1 handshake
OpRSASignSHA1 0x03 RSA PKCS#1 v1.5 signature over SHA1
OpRSASignSHA224 0x04 RSA PKCS#1 v1.5 signature over SHA224
OpRSASignSHA256 0x05 RSA PKCS#1 v1.5 signature over SHA256
OpRSASignSHA384 0x06 RSA PKCS#1 v1.5 signature over SHA384
OpRSASignSHA512 0x07 RSA PKCS#1 v1.5 signature over SHA512
OpRSAPSSSignSHA256 0x35 RSASSA-PSS signature over SHA256 — primary RSA operation in TLS 1.3
OpRSAPSSSignSHA384 0x36 RSASSA-PSS signature over SHA384
OpRSAPSSSignSHA512 0x37 RSASSA-PSS signature over SHA512

ECDSA operations

opcode label Wire value Description
OpECDSASignMD5SHA1 0x12 ECDSA signature over MD5+SHA1 combined hash
OpECDSASignSHA1 0x13 ECDSA signature over SHA1
OpECDSASignSHA224 0x14 ECDSA signature over SHA224
OpECDSASignSHA256 0x15 ECDSA signature over SHA256 — most common in TLS 1.2 and TLS 1.3
OpECDSASignSHA384 0x16 ECDSA signature over SHA384
OpECDSASignSHA512 0x17 ECDSA signature over SHA512

Other signing

opcode label Wire value Description
OpEd25519Sign 0x18 Ed25519 signature over an arbitrary-length payload (not a pre-hashed digest)

Sealing and infrastructure operations

opcode label Wire value Description
OpSeal 0x21 Encrypt a blob using the server's sealing key — used for TLS session tickets
OpUnseal 0x22 Decrypt a blob previously encrypted by OpSeal. Returns ErrExpired if the sealing key has rotated
OpRPC 0x23 Execute a named function registered on the server. Available to all connection types
OpCustom 0x24 Execute a custom function set in the server configuration. Available to unrestricted connections only
OpPing 0xF1 Health check — the server echoes the payload back as OpPong with no HSM or key lookup involved

keyless_request_exec_duration_per_opcode

Type: Histogram
Labels: type, error

Measures the time to execute a single operation, from when processing begins to when a response is produced. For operations backed by a PKCS#11 HSM, this includes the full time waiting for a session from the pool plus the HSM cryptographic operation time.

This metric does not include time a request spends waiting for a connection semaphore slot. That is captured by keyless_request_total_duration_per_opcode.

type label

Opcodes are grouped into coarser categories for this label:

type label Opcodes included
rsa OpRSADecrypt, all OpRSASign*, all OpRSAPSSSign*
ecdsa All OpECDSASign*
ed25519 OpEd25519Sign
rpc OpRPC
custom OpCustom
other OpSeal, OpUnseal, OpPing, OpPong, OpResponse, OpError
unknown Any unrecognised opcode byte

:::note OpPing is grouped into other alongside OpSeal and OpUnseal. Ping round-trip latency cannot be separated from seal and unseal operation latency in this metric. :::

error label

For successful requests the value is no error. All other values indicate a failed operation.

error label Description Common cause
no error Operation completed successfully —
cryptography error HSM or signing operation failed PKCS#11 session pool exhaustion (resource pool timed out), HSM returned an error, key type mismatch
key not found due to no matching SKI/SNI/ServerIP Key lookup returned no result Key not loaded in keystore, incorrect SKI in request
read failure I/O read error during the operation Disk error reading key file
version mismatch Protocol version not supported Client and server version skew
bad opcode Unknown opcode received OpCustom sent with no custom handler configured
unexpected opcode A response opcode was used as a request Client sent OpPong, OpResponse, or OpError as a request
malformed message TLV parse failure Corrupt or truncated packet
internal error Non-cryptographic server-side failure Sealer is nil, RPC dispatch error
certificate not found Certificate lookup failed Certificate not loaded
sealing key expired OpUnseal blob is too old to decrypt TLS session ticket key rotation — blob sealed with a key that has since been retired
remote configuration error Remote key server is misconfigured Key points to an unreachable or misconfigured remote key server

keyless_request_total_duration_per_opcode

Type: Histogram
Labels: type, error (same values as keyless_request_exec_duration_per_opcode)

Measures the total time to satisfy a request, from when the request packet is read off the wire to when the response bytes are written back to the client.

total_duration = exec_duration + response_write_time

Both timestamps are captured after the connection semaphore is already held, so semaphore queue wait time is not included in either histogram. Under normal load, total duration and exec duration are approximately equal. A growing gap between them indicates slow writes back to the client — for example, network backpressure between the key server and the Cloudflare edge.


keyless_key_load_duration

Type: Histogram
Labels: None

Measures the time taken by the keystore to locate and return the private key for each request, keyed by SKI, SNI, and server IP.

This metric is recorded for all signing and decryption operations: OpRSADecrypt, all OpRSASign*, all OpRSAPSSSign*, all OpECDSASign*, and OpEd25519Sign.

It is not recorded for OpPing, OpSeal, OpUnseal, OpRPC, or OpCustom, which do not require a private key lookup.


keyless_failed_connection

Type: Counter
Labels: None

Counts connection-level transport failures. This metric reflects problems at the network or TLS layer — it does not count signing errors or key lookup failures, which are reported in the error label of the duration histograms.

Scenario Counted?
TLS handshake failure No
Client disconnected before TLS handshake (EOF) No
Failure determining connection trust level after TLS Yes
Non-EOF read error on an established connection Yes
Write error when delivering a response Yes
Read timeout — graceful connection drain No
Signing error, including PKCS#11 pool timeout No
Key not found No

certificate_expiration_timestamp_seconds

Type: Gauge
Labels: source, serial_no, cn, hostnames, ca, server, client

Reports the expiration time (NotAfter) of each certificate loaded by the key server as a Unix timestamp. One time series is emitted per certificate.

This metric is updated:

Label Description
source File path for startup certs; listener: <addr> for peer certs from incoming connections
serial_no Certificate serial number
cn Subject Common Name
hostnames Sorted, comma-separated list of DNS Subject Alternative Names
ca 1 if the certificate is a CA certificate, 0 otherwise
server 1 if the certificate includes ExtKeyUsageServerAuth, 0 otherwise
client 1 if the certificate includes ExtKeyUsageClientAuth, 0 otherwise

:::note server_utilization is a registered GaugeVec metric that is never written to by the key server. Because no label values are ever set, it emits no time series in the /metrics output at all. Do not use it. :::


Example PromQL queries

Signing throughput by key type

sum by (opcode) (rate(keyless_requests[1m]))

Error rate by error type

sum by (error) (
  rate(keyless_request_exec_duration_per_opcode_count{error!="no error"}[5m])
)

99th percentile signing latency for RSA

histogram_quantile(
  0.99,
  rate(keyless_request_exec_duration_per_opcode_bucket{type="rsa"}[5m])
)

A value approaching 10 seconds indicates PKCS#11 session pool exhaustion. Refer to Scaling and benchmarking and your HSM documentation for guidance on increasing the session pool size.

99th percentile key load latency

histogram_quantile(0.99, rate(keyless_key_load_duration_bucket[5m]))

A spike here without a corresponding spike in exec duration suggests the keystore lookup itself is slow — a possible disk I/O issue or PKCS#11 object enumeration delay.

Connection failure rate

rate(keyless_failed_connection_total[5m])

A sustained non-zero rate indicates network or TLS problems between the Cloudflare network and your key server.

Alert on certificate expiry within 30 days

(certificate_expiration_timestamp_seconds - time()) / 86400 < 30

Scaling and benchmarking

Cloudflare's Keyless SSL technology was designed to scale to accommodate any sized workload using vertical and horizontal scaling, and pre-computation techniques wherever possible, such as ECDSA. The goals of the architectural design of the key server are to minimize latency while maximizing signing operations per second.

Each key server uses a worker pool model, with incoming client connections handled by its own pair of reader/writer goroutines and cryptographic work done in separate worker goroutines pulled from a global pool.

Where needed, multiple key servers can be deployed and balanced between using your preferred ingress load balancing configuration. For full high availability, make sure to deploy sufficient key servers to handle twice the expected workload.


Key type

Key servers support both ECDSA and RSA keys, though signatures for RSA are an order of magnitude more expensive to compute and thus consider type of keys used when planning the number of key servers in your deployment.

ECDSA signing can be broken down into two steps. Since the first step — generating random values (to be used later with the private key and message to be signed) — represents the majority of the computational cost, we pre-generate these random values to significantly reduce latency. ECDSA signing requests are computationally isolated from RSA signing requests using separate worker pools to keep them as fast as possible.

Additional details can be found in the gokeyless server readme file file.


Benchmarks

We conducted benchmarks using Cloudflare's gokeyless bench tool on a then current-generation, compute-optimized EC2 instance (c5.xlarge). This particular instance has 4 vCPUs powered by 3.0 GHz Intel Xeon processors:

c5$ cat /proc/cpuinfo|grep "model name"
model name	: Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz
model name	: Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz
model name	: Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz
model name	: Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz

By default, bench runs with one worker goroutine per core (4) and a maximum number of operating system threads equal to the total number of cores (in this case, GOMAXPROCS=4). As expected and explained above, ECDSA signature performance far exceeds that of RSA. The results show that each core of this c5.xl machine can perform over 10,000 ECDSA signing operations/second and approximately 200 RSA signing operations/second.

When planning your deployment, determine the maximum number of new TLS connections per second you expect to terminate using a given key server and scale accordingly. For full high availability, each data center running keyless should be able to terminate the full workload that you anticipate.

Results

ECDSA

c5$ bench -ski $ECDSA_SKI -op ECDSA-SHA256 -bandwidth -duration 60s
Total operations completed: 2661570
Average operation duration: 22.543µs

RSA

c5$ bench -ski $RSA_SKI -op RSA-SHA256 -bandwidth -duration 60s
Total operations completed: 46560
Average operation duration: 1.288659ms.

Automatic key exchange to origins

import { DashButton, Steps } from "~/components";

Automatic key exchange allows Cloudflare to establish faster connections to origin servers by predicting which key agreements origins support. When establishing a TLS 1.3 connection to the origin, Cloudflare sends a key share for the predicted key agreement in the initial ClientHello, which can remove one network round trip by avoiding a HelloRetryRequest.

This feature is separate from your SSL/TLS encryption mode. The encryption mode controls whether Cloudflare uses HTTPS and validates your origin certificate. Automatic key exchange controls the key shares sent when starting an HTTPS connection. The same preference is applied for all of a zone's origins.

Requirements and scope

Automatic key exchange applies when the connection meets these requirements:

Automatic key exchange is available on all plans. It only affects new TLS connections. Requests that reuse an existing connection do not perform another key exchange.

Cloudflare Tunnel uses a separate post-quantum connection between cloudflared and Cloudflare.

The setting applies to all outbound connections for the zone, including fetch() requests from Workers. If the zone has multiple active origins, Cloudflare derives one preference from their traffic-weighted results.

How automatic selection works

Cloudflare scans active origins approximately every 24 hours. The scan checks the TLS key agreements that each origin supports and prefers.

When an origin supports both classical and post-quantum key agreements, Cloudflare prefers a post-quantum key agreement.

Cloudflare then applies the selected preference in stages:

  1. Cloudflare sends the selected key share to 1% of traffic.
  2. Cloudflare monitors connection failures and HelloRetryRequest rates.
  3. A healthy change increases through 10%, 25%, 50%, 75%, and 100% of traffic.
  4. An unhealthy change rolls back to the previous setting.

For each connection, Cloudflare sends the preferred key share first. Cloudflare also advertises the other key agreements allowed by your compliance requirements. An origin can request another advertised key share with a HelloRetryRequest. This adds one round trip but does not break the connection.

After a successful rollout, Cloudflare keeps the preference until a later scan finds a better option. Cloudflare selects X25519MLKEM768 when the origin supports it and compliance requirements allow it. Otherwise, Cloudflare selects a supported classical key agreement.

Cloudflare uses standardized X25519MLKEM768 for automatic post-quantum selection.

Configuration options

To configure automatic key exchange in the dashboard:

1. In the Cloudflare dashboard, go to the **SSL/TLS Overview** page.
  1. Under Origin connection & post-quantum encryption, turn Automatic key exchange on or off.
  2. Select any Compliance requirements. These requirements apply only to TLS 1.3 connections. Leave both options unselected to allow all supported key agreements.

The settings provide two separate controls. Automatic key exchange controls whether Cloudflare scans and reorders preferred key agreements. Compliance requirements control which key agreements Cloudflare may use for automatic selection on TLS 1.3 connections.

Automatic key exchange

Automatic key exchange is on for all existing zones and on by default for new zones.

The setting has these options:

Setting Behavior
On Cloudflare scans your origins and sends the zone's preferred key share.
Off Cloudflare does not scan or reorder key shares. It uses the default order for your selected compliance requirements.

Turning off automatic key exchange does not change your compliance requirements.

Compliance requirements

Compliance requirements apply only to TLS 1.3 connections. They filter the key agreements that Cloudflare can advertise or select. Automatic key exchange never selects an algorithm outside this allowed set.

The available selections are:

Selection API value Behavior
No selection [] Allows supported classical and post-quantum key agreements.
Post-quantum hybrid ["pqh"] Allows only hybrid post-quantum key agreements.
Federal Information Processing Standards (FIPS) ["fips"] Allows only key agreements that meet FIPS requirements.
Post-quantum hybrid and FIPS ["pqh", "fips"] Allows only key agreements that satisfy both requirements.

Cloudflare rejects a combination if the selected requirements have no key agreement in common. Changing a compliance requirement stops any active rollout. A later scan selects from the new allowed set.

Origin Post-Quantum Encryption API

The Origin Post-Quantum Encryption API remains available. Requests to this API are no-ops and do not change a zone's post-quantum key agreement behavior. Cloudflare plans to deprecate this API, but a deprecation date has not been established.

Use Automatic key exchange and Compliance requirements to configure post-quantum key agreement behavior.

Cipher suites

Refer to the following list to know what cipher suites Cloudflare presents to origin servers during an SSL/TLS handshake.

:::note

Refer to cipher suites supported at Cloudflare's global network to know what cipher suites Cloudflare presents to browsers and other user agents. :::

The list order is based on how the cipher suites appear in the ClientHello, communicating Cloudflare's preference.

Supported cipher suites by protocol

Cipher name TLS 1.0 TLS 1.1 TLS 1.2 TLS 1.3
AEAD-AES128-GCM-SHA256 [^1] ❌ ❌ ❌ ✅
AEAD-AES256-GCM-SHA384 [^1] ❌ ❌ ❌ ✅
AEAD-CHACHA20-POLY1305-SHA256 [^1] ❌ ❌ ❌ ✅
ECDHE-ECDSA-AES128-GCM-SHA256 ❌ ❌ ✅ ❌
ECDHE-RSA-AES128-GCM-SHA256 ❌ ❌ ✅ ❌
ECDHE-RSA-AES128-SHA ✅ ✅ ✅ ❌
AES128-GCM-SHA256 ❌ ❌ ✅ ❌
AES128-SHA ✅ ✅ ✅ ❌
ECDHE-ECDSA-AES256-GCM-SHA384 ❌ ❌ ✅ ❌
ECDHE-RSA-AES256-GCM-SHA384 ❌ ❌ ✅ ❌
ECDHE-RSA-AES256-SHA384 ❌ ❌ ✅ ❌
AES256-SHA ✅ ✅ ✅ ❌
DES-CBC3-SHA ✅ ❌ ❌ ❌

TLS 1.3 cipher suites

Although TLS 1.3 uses the same cipher suite space as previous versions of TLS, TLS 1.3 cipher suites are defined differently, only specifying the symmetric ciphers, and cannot be used for TLS 1.2 (RFC 8446).

Similarly, TLS 1.2 and lower cipher suites cannot be used with TLS 1.3. BoringSSL also hard-codes cipher preferences in the order above for TLS 1.3.

Based on BoringSSL, Cloudflare system will return the names listed above. However, the corresponding names defined in RFC 8446 are the following:

Match on origin

Cloudflare will present the cipher suites to your origin and your server will select whichever cipher suite it prefers.

However, if you want to ensure that your origin server supports the same cipher suites that Cloudflare supports at our global network and you use NGINX for TLS termination on your origin, you can apply the following configuration:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ecdh_curve X25519:P-256:P-384;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE+AES128:RSA+AES128:ECDHE+AES256:RSA+AES256:ECDHE+3DES:RSA+3DES;
ssl_prefer_server_ciphers on;

[^1]: Refer to TLS 1.3 cipher suites for details.

Custom Origin Trust Store

import { Render, DashButton } from "~/components";

By default, Cloudflare's global network maintains a list of publicly trusted certificate authorities. This means that when using Full (strict) encryption mode, Cloudflare will only trust origin server certificates issued by a CA included in this trust store.


When a CA has been uploaded to Custom Origin Trust Store, Cloudflare will ignore all default publicly trusted CAs and exclusively use the CA or CAs that have been uploaded to authenticate the origin server.

Availability

To get access to Custom Origin Trust Store, Advanced Certificate Manager must be enabled on the zone.

Post-quantum certificate authorities

Custom Origin Trust Store accepts ML-DSA (FIPS 204) post-quantum certificate authorities. Refer to Post-quantum signatures for certificate generation and upload guidance.

How to

To manage origin trust stores in the dashboard:

  1. Go to the Origin Server page.

  2. Select the Custom Origin Trust Store tab.

  3. Select Upload trust store to add a CA certificate, or use the table to manage existing trust stores.

To manage origin trust stores using the API, refer to the API commands.

Limitations

With Full (strict) encryption mode enabled, if your uploaded CA expires and no alternative CAs are valid within the trust store, Cloudflare will not be able to properly authenticate connections to the origin server.

API commands

List Custom Origin Trust Store Details

Custom Origin Trust Store Details

Upload Custom Origin Trust Store

Delete Custom Origin Trust Store

Origin server

import { DirectoryListing } from "~/components"

Learn more about SSL/TLS protection options for your origin servers:

SSL/TLS Recommender

import { Render, TabItem, Tabs, DashButton } from "~/components";

The SSL/TLS Recommender helps you choose which Encryption mode is best for your application.

:::caution

Cloudflare is deprecating our SSL/TLS Recommender in favor of Automatic SSL/TLS.

:::

Availability

Free Pro Business Enterprise
Availability Yes Yes Yes Yes

Common tasks

Enable SSL/TLS recommendations

Then, you can enable the SSL/TLS recommender.

To enable SSL/TLS recommendations in the dashboard:

  1. In the Cloudflare dashboard, go to the SSL/TLS Overview page.

  2. For SSL/TLS Recommender, switch the toggle to On.

To adjust your SSL/TLS Recommender enrollment with the API, send a PATCH request with the enabled parameter set to your desired setting (true or false).

Manually trigger a new scan

Once you enable it, the recommender runs future scans periodically — typically every two days — and sends notifications if new recommendations become available.

To manually re-trigger a new scan, disable and then re-enable SSL/TLS recommendations.

How it works

AWS integration

import { Render, APIRequest } from "~/components";

This guide will walk you through how to set up per-hostname authenticated origin pulls to securely connect to an AWS Application Load Balancer using mutual TLS verify.

Before you begin

1. Generate a custom certificate

2. Configure AWS Application Load Balancer

  1. Upload the rootca.cert to an S3 bucket.
  2. Create a trust store at your EC2 console, indicating the S3 URI where you uploaded the certificate.
  3. Create an EC2 instance and install an HTTPD daemon. Choose an instance type according to your needs - it can be a minimal instance eligible to AWS Free Tier. This tutorial was based on an example using t2.micro and Amazon Linux 2023.
sudo yum install -y httpd
sudo systemctl start httpd
  1. Create a target group for your Application Load Balancer.
    • Choose Instances as target type.
    • Specify port HTTP/80.
  2. After you finish configuring the target group, confirm that the target group is healthy.
  3. Configure a load balancer and a listener.
    • Choose the Internet-facing scheme.
    • Switch the listener to port 443 so that the mTLS option is available, and select the target group created in previous steps.
    • For Default SSL/TLS server certificate, choose Import certificate > Import to ACM, and add the certificate private key and body.
    • Under Client certificate handling, select Verify with trust store.
  4. Save your settings.
  5. (Optional) Run the following commands to confirm that the Application Load Balancing is asking for the client certificate.
openssl s_client -verify 5 -connect <your-application-load-balancer>:443 -quiet -state

Since you have not yet uploaded the certificate to Cloudflare, the connection should fail (read:errno=54, for example).

You can also run curl --verbose and confirm Request CERT (13) is present within the SSL/TLS handshake:

curl --verbose https://<your-application-load-balancer>
...
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
...

3. Configure Cloudflare

  1. Upload the certificate you created in Step 1 to Cloudflare. You should use the leaf certificate, not the root CA.
  1. Associate the certificate with the hostname that should use it.

<APIRequest path="/zones/{zone_id}/origin_tls_client_auth/hostnames" method="PUT" json={{ config: [ { enabled: true, cert_id: "<CERT_ID>", hostname: "<YOUR_HOSTNAME>", }, ], }} />

:::note

Make sure your encryption mode is set to Full or higher. If you only want to adjust this setting for a specific hostname, use Configuration Rules. :::


Roll back the Cloudflare configuration

About

When visitors request content from your domain, Cloudflare first attempts to serve content from the cache. If this attempt fails, Cloudflare sends a request — or an origin pull — back to your origin web server to get the content.

Authenticated Origin Pulls makes sure that all of these origin pulls come from Cloudflare. Put another way, Authenticated Origin Pulls ensures that any HTTPS requests outside of Cloudflare will not receive a response from your origin.

This block also applies for requests to unproxied DNS records in Cloudflare.

:::caution

The Cloudflare-provided certificate used by global AOP is not exclusive to your account. It only guarantees that a request is coming from the Cloudflare network.

For stricter security, set up zone-level or per-hostname AOP with your own certificate and consider other security measures for your origin.

:::

Detailed explanation

Cloudflare enforces authenticated origin pulls by adding an extra layer of TLS client certificate authentication when establishing a connection between Cloudflare and the origin web server.

For more details, refer to the introductory blog post.


Types of handshakes

For more details, refer to What is a TLS handshake?.

Standard TLS handshake

Diagram showing the Standard TLS handshake

Client authenticated TLS handshake

Diagram showing the client authenticated TLS handshake

Comparison diagrams

Without Authenticated Origin Pulls, Cloudflare performs standard TLS handshakes between a client device and Cloudflare and Cloudflare and your origin. This is true even if you have Full or Full (strict) encryption modes enabled.

    flowchart TD
      accTitle: Connection diagram without Authenticated Origin Pulls
      A[End user query for <code>example.com</code>] --Standard TLS Handshake--> B[Cloudflare network]
      B --Standard TLS Handshake--> C[Origin server]
      D[External device] --Standard TLS Handshake ----> C

This lack of authentication means that - even if your origin is protected behind Cloudflare - attackers with your origin's IP address will still receive a response from your origin for HTTPS requests.

With Authenticated Origin Pulls, Cloudflare performs standard TLS handshakes between a client device and Cloudflare, but a client-authenticated TLS handshake between Cloudflare and your origin.

    flowchart TD
      accTitle: Connection diagram with Authenticated Origin Pulls
      A[End user query for <code>example.com</code>] --Standard TLS Handshake--> B[Cloudflare network]
      B --Client authenticated TLS Handshake--> C[Origin server]
      D[External device] --Standard TLS Handshake -----x C

This additional layer of authentication ensures that any HTTPS requests outside of Cloudflare will not receive a response from your origin.

Authenticated Origin Pulls (mTLS)

import { Render } from "~/components";

Authenticated Origin Pulls (AOP) helps ensure requests to your origin server come from the Cloudflare network, which provides an additional layer of security on top of Full or Full (strict) encryption modes.

:::caution[Check your encryption mode] Authenticated Origin Pulls does not apply when your SSL/TLS encryption mode is set to Off or Flexible. :::

Without AOP, anyone who discovers your origin server's IP address can send requests directly, bypassing Cloudflare and all its protections. When you combine AOP with the Cloudflare Web Application Firewall (WAF), your origin only accepts requests that have passed through Cloudflare, which means every request is evaluated by the WAF before reaching your server.

:::note[Not compatible with Cloudflare Tunnel] AOP is not compatible with origins connected through Cloudflare Tunnel. Tunnel uses outbound-only connections from your origin, so there is no inbound listener for Cloudflare to present a client certificate to. If your origin is reachable through Cloudflare Tunnel, origin traffic is already authenticated using the tunnel's connector credentials, and AOP settings have no effect on that hostname. :::

Availability

Free Pro Business Enterprise
Availability Yes Yes Yes Yes

Configuration levels

AOP has three independent configuration levels. Each uses its own certificate and enablement setting, and each requires configuration on your origin server. Refer to the specific setup guides for details.

:::note

:::

When to use your own certificate

Global AOP uses a Cloudflare-provided certificate shared across all accounts, so it only proves a request came from the Cloudflare network — not from your account specifically. If you need to guarantee requests come from your account, set up zone-level or per-hostname AOP with your own certificate.

Using your own certificate is also required for FIPS compliance. For broader origin protection guidance, refer to Protect your origin server.

Post-quantum certificates

Zone-level and per-hostname AOP support ML-DSA (FIPS 204) post-quantum client certificates. Refer to Post-quantum signatures for certificate generation and upload guidance.

Global

import { Render, Tabs, TabItem, DashButton } from "~/components";

When you enable global Authenticated Origin Pulls (AOP), Cloudflare uses a Cloudflare-provided client certificate for all proxied traffic to your zone. This certificate is shared across all Cloudflare accounts and guarantees that the request is coming from the Cloudflare network.

Global, zone-level, and per-hostname AOP are independent configurations. Enabling or disabling one does not affect the others.

Before you begin

1. Download the Cloudflare certificate

Download the Cloudflare authenticated origin pull certificate (.PEM) and upload it to your origin server. This certificate is not the same as the Cloudflare Origin CA certificate.

2. Configure origin to accept client certificates

<Render file="aop-configure-origin" product="ssl" params={{ one: "Rename the downloaded .PEM file and upload it to /path/to/origin-pull-ca.pem before applying the settings.", two: " Rename the downloaded .PEM file and upload it to /etc/nginx/certs/cloudflare.crt before applying the settings.", }} />

3. Enable global Authenticated Origin Pulls

  1. Go to the Origin Server page.

  2. Select the Authenticated Origin Pulls tab.

  3. In the Global section, switch the toggle to On.

To enable or disable global Authenticated Origin Pulls with the API, use the Edit zone setting endpoint with tls_client_auth as the setting name in the URI path, and the value parameter set to your desired setting ("on" or "off").

4. Enforce validation check on your origin

Setup

import { DirectoryListing } from "~/components"

Manage certificates

import { APIRequest } from "~/components";

Refer to the following sections to learn how to manage certificates used with zone-level and per-hostname Authenticated Origin Pulls. Global AOP uses a Cloudflare-provided certificate and does not require certificate management.


Expired certificates

Cloudflare does not delete client certificates upon expiration unless you send a delete request to the Cloudflare API for the relevant certificate (Delete a zone-level certificate or Delete a hostname-level certificate). If your origin only accepts a valid client certificate, it will drop requests when the certificate expires.

Make sure you have notifications set up to get alerts 30 days and 14 days before an AOP certificate expires.


Use specialized certificates

To apply different client certificates simultaneously at the zone and hostname level, you can combine zone-level and per-hostname custom certificates.

First, set up zone-level AOP using your certificate. Then, upload specialized certificates for individual hostnames. Per-hostname certificates take precedence over zone-level certificates for the specified hostname.


Replace a certificate without downtime via API

:::caution[No automatic removal] Cloudflare does not delete client certificates upon expiration unless you send a delete request to the Cloudflare API for the relevant certificate (Delete a zone-level certificate or Delete a hostname-level certificate). :::

Per-hostname

  1. Upload the new certificate.
  2. List your certificates and note the ID for the certificate you uploaded.
  3. Enable Authenticated Origin Pulls for the specific hostname, using the ID obtained in step 2 to specify the certificate you want to use:

<APIRequest path="/zones/{zone_id}/origin_tls_client_auth/hostnames" method="PUT" json={{ config: [ { enabled: true, hostname: "", cert_id: "<CERT_ID>", }, ], }} />

:::note If you keep both certificates, the API will state active for both but the most recently deployed certificate will be the one enabled and used. :::

Zone-level

  1. Upload the new certificate.
  2. Check whether new certificate is Active.
  3. Once certificate is active, delete the previous certificate.

:::note If you keep both certificates, the API will state active for both but the most recently deployed certificate will be the one enabled and used. :::

Per-hostname

import { AvailableNotifications, Render, Details, Tabs, TabItem, DashButton, } from "~/components";

When you enable per-hostname Authenticated Origin Pulls (AOP), all proxied traffic to the specified hostname is authenticated at the origin web server using a certificate that you upload. You can use client certificates from your Private PKI to authenticate connections from Cloudflare.

Global, zone-level, and per-hostname AOP are independent configurations. Enabling or disabling one does not affect the others. Per-hostname certificates take precedence over zone-level and global certificates for the specified hostname.

Before you begin

:::caution[Warning]

:::

Refer to the steps below for an example of how to generate a custom certificate using OpenSSL. The CA root certificate that you use to issue the custom certificate should be the same CA that you will upload to your origin.

1. Upload custom certificate

  1. Go to the Origin Server page.

  2. Select the Authenticated Origin Pulls tab.

  3. In the Per-hostname section, select Upload certificate.

  4. Paste the certificate and private key, then select Continue. :::note You must upload a leaf certificate. If you upload a root CA instead, the upload will fail. :::

  5. Review your certificate details, save the certificate ID for future reference, and select Continue.

  6. On the Associate Hostnames page, enter the fully qualified domain name that should use this certificate and select Add for each one. You can also skip this step and associate hostnames later.

  7. Select Save to confirm.

Use the Upload a Hostname Client Certificate endpoint to upload your custom certificate.

:::note

You must upload a leaf certificate. If you upload a root CA instead, the API will return a missing leaf certificate error. :::

In the API response, save the certificate id since it will be required in step 3.

2. Configure origin to accept client certificates

<Render file="aop-configure-origin" params={{ one: " ", two: " " }} product="ssl" />

3. Enable Authenticated Origin Pulls for the hostname

:::note For per-hostname AOP, the enablement happens as you associate a hostname. If you had already associated hostnames as you uploaded the certificate, you can skip this step. :::

  1. Go to the Origin Server page.

  2. Select the Authenticated Origin Pulls tab.

  3. In the Per-hostname section, find the certificate that should be used and associate the hostname with it.

If you had set up logging on your origin during step 2, test and confirm that Authenticated Origin Pulls is working.

Use the Enable or Disable a Hostname for Client Authentication endpoint to enable Authenticated Origin Pulls for specific hostnames.

If you had set up logging on your origin during step 2, test and confirm that Authenticated Origin Pulls is working.

4. Enforce validation check on your origin

5. (Optional) Set up expiration alerts

You can configure alerts to receive notifications before your AOP certificates expire.

Further options

Refer to Manage certificates for further options.

To learn how to remove the configuration, refer to Rollback.

Roll back per-hostname AOP

import { Render } from "~/components";

If you need to disable or remove your per-hostname Authenticated Origin Pulls configuration, follow these steps.

:::note

:::

Zone-level

import { AvailableNotifications, Render, Details, Tabs, TabItem, DashButton, } from "~/components";

When you enable zone-level Authenticated Origin Pulls (AOP), all proxied traffic to your zone is authenticated at the origin web server using a certificate that you upload. Unlike global AOP, which uses a Cloudflare-provided certificate shared across all accounts, zone-level AOP uses your own certificate for stricter security.

Global, zone-level, and per-hostname AOP are independent configurations. Enabling or disabling one does not affect the others.

Before you begin

Make sure your zone is using an SSL/TLS encryption mode of Full or higher.

:::caution

Zone-level AOP certificates are also applied to custom hostnames configured on a Cloudflare for SaaS zone. If you need a different AOP certificate for different custom hostnames, use per-hostname AOP.

:::

Zone-level AOP requires you to upload your own certificate. Refer to the steps below for an example of how to generate a custom certificate using OpenSSL. The CA root certificate that you use to issue the custom certificate should be the same CA that you will upload to your origin.

1. Upload your certificate to Cloudflare

  1. Go to the Origin Server page.

  2. Select the Authenticated Origin Pulls tab.

  3. In the Zone-level section, select Upload certificate.

  4. Paste the certificate and private key, then select Continue. :::note You must upload a leaf certificate. If you upload a root CA instead, the upload will fail. :::

  5. Review your certificate details, save the certificate ID for future reference, and select Done.

Use the Upload a zone-level client certificate endpoint to upload your certificate.

:::note

You must upload a leaf certificate. If you upload a root CA instead, the API will return a missing leaf certificate error. :::

2. Upload the CA certificate to your origin

Upload the CA root certificate used to sign your client certificate to your origin server. Your origin will use this CA certificate to verify the client certificate presented by Cloudflare.

3. Configure origin to accept client certificates

<Render file="aop-configure-origin" product="ssl" params={{ one: " ", two: " ", }} />

4. Enable zone-level Authenticated Origin Pulls

  1. Go to the Origin Server page.

  2. Select the Authenticated Origin Pulls tab.

  3. In the Zone-level section, switch the toggle to On.

Use the Set Enablement for Zone endpoint to enable zone-level Authenticated Origin Pulls.

:::caution

This endpoint is separate from the global AOP toggle, which uses the zone settings tls_client_auth setting. Make sure you use the correct endpoint for the configuration you intend.

:::

5. Enforce validation check on your origin

6. (Optional) Set up expiration alerts

You can configure alerts to receive notifications before your AOP certificates expire.

Further options

Refer to Manage certificates for further options.

Cloudflare origin CA

import { Details, Render, TabItem, Tabs, DashButton, GlossaryTooltip, } from "~/components";

If your origin only receives traffic from proxied records, use Cloudflare origin CA certificates to encrypt traffic between Cloudflare and your origin web server and reduce bandwidth consumption. Once deployed, these certificates are compatible with Strict SSL mode.

For more background information on origin CA certificates, refer to the introductory blog post.

:::caution[API Access required] Users who do not have API Access will receive an error while trying to create or revoke an origin CA certificate. Refer to Troubleshooting for guidance. :::

Availability

Free Pro Business Enterprise
Availability Yes Yes Yes Yes

:::note Using Cloudflare origin CA certificates does not prevent you from using delegated DCV. :::

:::note[Known limitation] Cloudflare does not currently send expiration notifications for origin CA certificates. If you rely on long-lived origin CA certificates, track their expiration in your own certificate inventory or monitoring system. :::


Deploy an Origin CA certificate

1. Create an Origin CA certificate

To create an Origin CA certificate in the dashboard:

  1. Go to the Origin Server page.

  2. On the Origin Certificates tab, select Create Certificate.

  3. Choose either:

    • Generate private key and CSR with Cloudflare: Private key type can be RSA or ECC.
    • Use my private key and CSR: Paste the Certificate Signing Request into the text field.
  4. List the hostnames (including wildcards) the certificate should protect with SSL encryption. The zone apex and first level wildcard hostname are included by default.

  5. Choose a Certificate Validity period.

  6. Select Create.

  7. Choose the Key Format:

    • Servers using OpenSSL — like Apache and NGINX — generally expect PEM files (Base64-encoded ASCII), but also work with binary DER files.
    • Servers using Windows and Apache Tomcat require PKCS#7 (a .p7b file).
  8. Copy the signed Origin Certificate and Private Key into separate files. For security reasons, you cannot see the Private Key after you exit this screen.

  9. Select OK.

:::note For details about working with certificates programmatically, refer to API calls. :::

2. Install Origin CA certificate on origin server

To add an Origin CA certificate to your origin web server

  1. Upload the Origin CA certificate (created in Step 1) to your origin web server.
  2. Update your web server configuration:

:::note If you do not see your server in the list above, search the DigiCert documentation or contact your hosting provider, web admin, or server vendor. :::

  1. (Required for some) Upload the Cloudflare CA root certificate to your origin server. This can also be referred to as the certificate chain.
  2. Enable SSL and port 443 at your origin web server.

3. Change SSL/TLS mode

After you have installed the Origin CA certificate on your origin web server, update the SSL/TLS encryption mode for your application.

If all your origin hosts are protected by Origin CA certificates or publicly trusted certificates:

  1. Go to the SSL/TLS overview page.

  2. For SSL/TLS encryption mode, select Full (strict).

If you have origin hosts that are not protected by certificates, set the SSL/TLS encryption mode for a specific application to Full (strict) by using a Page Rule.

:::caution

:::

Revoke an Origin CA certificate

If you misplace your key material or do not want a certificate to be trusted, you may want to revoke your certificate. You cannot undo this process.

To prevent visitors from seeing warnings about an insecure certificate, you may want to set your SSL/TLS encryption to Full or Flexible before revoking your certificate. Do this globally via the Cloudflare dashboard or for a specific hostname via a Page Rule.

To revoke a certificate:

  1. Go to the Origin Server page.

  2. On the Origin Certificates tab, choose a certificate.

  3. Select Revoke.

Additional details

Cloudflare Origin CA root certificate

Some origin web servers require upload of the Cloudflare Origin CA root certificate or certificate chain. Use the following links to download either an ECC or an RSA version and upload to your origin web server:

Hostname and wildcard coverage

Certificates may be generated with up to 200 individual Subject Alternative Names (SANs). A SAN can take the form of a fully-qualified domain name (www.example.com) or a wildcard (*.example.com). You cannot use IP addresses as SANs on Cloudflare origin CA certificates.

Wildcards may only cover one level, but can be used multiple times on the same certificate for broader coverage (for example, *.example.com and *.secure.example.com may co-exist).

API calls

To automate processes involving Origin CA certificates, use the following API calls. To authenticate, use an API token with Permissions that include Zone-SSL and Certificates-Edit.

Operation Method Endpoint
List certificates GET certificates?zone_id=<<ZONE_ID>>
Create certificate POST certificates
Get certificate GET certificates/<<ID>>
Revoke certificate DELETE certificates/<<ID>>

Troubleshooting

If you find NET::ERR_CERT_AUTHORITY_INVALID or other issues after setting up Cloudflare origin CA, refer to troubleshooting.

Troubleshooting Cloudflare origin CA

import { GlossaryTooltip, Render, DashButton } from "~/components";

Consider the following common issues and troubleshooting steps when using Cloudflare origin CA.

NET::ERR_CERT_AUTHORITY_INVALID

Cause

This also means that SSL Labs or similar SSL validators are expected to flag the certificate as invalid.

Solutions

The issuer of this certificate could not be found

Cause

Some origin web servers require that you upload the Cloudflare origin CA root certificate or certificate chain.

Solution

Use the following links to download either an ECC or an RSA version and upload to your origin web server:

The certificate is not trusted in all web browsers

Cause

Apache cPanel requires that you upload the Cloudflare origin CA root certificate or certificate chain.

Solution

Use the following link to download an RSA version of the root certificate and upload it to your origin web server:

This zone is either not part of your account, or you do not have access to it

When trying to generate an Origin CA on the dashboard, you find the error Failed to validate requested hostname <hostname>: This zone is either not part of your account, or you do not have access to it.

Cause

This is a known issue where, whilst being created on the Cloudflare dashboard, Origin CA requires API access for the user creating the origin certificate. If the user does not have API Access, this error is returned.

Solution

Make sure that the user creating the certificate has access to the API. You can check in the account Members page.

Flexible

import { Render, TabItem, Tabs } from "~/components";

Setting your encryption mode to Flexible makes your site partially secure. Cloudflare allows HTTPS connections between your visitor and Cloudflare, but all connections between Cloudflare and your origin are made through HTTP. As a result, an SSL certificate is not required on your origin.

flowchart LR
    accTitle: Flexible SSL/TLS Encryption
    accDescr: With an encryption mode of Flexible, your application encrypts traffic between the visitor and Cloudflare, but not between Cloudflare and your server.
    A[Visitor] <--Encrypted--> B((Cloudflare))<--Unencrypted--> C[(Origin server)]

Use when

Choose this option when you cannot set up an SSL certificate on your origin or your origin does not support SSL/TLS.

Required setup

Prerequisites

Process

Limitations

:::caution

If your origin forces HTTPS by automatically redirecting HTTP requests to HTTPS, do not use Flexible mode. Because Cloudflare connects to your origin over HTTP, this creates a redirect loop that makes your site inaccessible. Use Full or Full (strict) mode instead.

Refer to ERR_TOO_MANY_REDIRECTS for troubleshooting guidance, or Enforce HTTPS connections to redirect traffic to HTTPS at the Cloudflare edge without setting up redirects at your origin.

:::

Flexible mode is only supported for HTTPS connections on port 443 (default port). Other ports using HTTPS will fall back to Full mode.

If your application contains sensitive information (personalized data, user login), use Full or Full (Strict) modes instead.


Full (strict)

import { Render, TabItem, Tabs } from "~/components";

When you set your encryption mode to Full (strict), Cloudflare does everything in Full mode but also enforces more stringent requirements for origin certificates.

flowchart LR
    accTitle: Full - Strict SSL/TLS Encryption
    accDescr: With an encryption mode of Full (strict), your application encrypts traffic going to and coming from Cloudflare.
    A[Visitor] <--Encrypted--> B((Cloudflare))<--Encrypted--> C[("Origin server (verified) #9989;")]

Use when

For the best security, choose Full (strict) mode whenever possible (unless you are an Enterprise customer).

Your origin needs to be able to support an SSL certificate that is:

:::note

In addition to Full (strict) encryption, you can also set up Authenticated Origin Pulls to ensure all requests to your origin are evaluated before receiving a response.

:::

Required setup

Prerequisites

Before enabling Full (strict) mode, make sure your origin:

Otherwise, your visitors may experience a 526 error.

Process

Limitations

Full

import { Stream, Render, TabItem, Tabs } from "~/components";

When you set your encryption mode to Full, Cloudflare allows HTTPS connections between your visitor and Cloudflare and makes connections to the origin using the scheme requested by the visitor. If your visitor uses http, then Cloudflare connects to the origin using plaintext HTTP and vice versa.

Use when

Choose Full mode when your origin can support an SSL certification, but — for various reasons — it cannot support a valid, publicly trusted certificate.

:::note

In addition to Full encryption, you can also set up Authenticated Origin Pulls to ensure all requests to your origin are evaluated before receiving a response.

:::

Required setup

Prerequisites

Before enabling Full mode, make sure your origin allows HTTPS connections on port 443 and presents a certificate (self-signed, Cloudflare Origin CA, or purchased from a Certificate Authority). Otherwise, your visitors may experience a 525 error.

Process

Limitations

The certificate presented by the origin will not be validated in any way. It can be expired, self-signed, or not even have a matching CN/SAN entry for the hostname requested.

Without using Full (strict), a malicious party could technically hijack the connection and present their own certificate.

Encryption modes

import { DirectoryListing, Render, TabItem, Tabs, APIRequest, } from "~/components";


If possible, Cloudflare strongly recommends using Full or Full (strict) modes to prevent malicious connections to your origin.

For more details on how encryption modes fit into the bigger picture of Cloudflare SSL/TLS protection, refer to Concepts.

Available encryption modes

Automatic SSL/TLS relies on the probes developed for the SSL/TLS Recommender to determine what encryption mode is the most secure and safest for a website to be set to. If there is a more secure option for your website (based on your origin certification or capabilities), Automatic SSL/TLS will find it and apply it for your domain. The other option, Custom SSL/TLS, will work exactly like the setting the encryption mode does today.

:::note We are gradually rolling out the new Automated SSL/TLS feature.

If your zone has not been migrated yet, you will only have Custom SSL/TLS options in your dashboard. :::

To understand how the various encryption modes affect your cache, refer to the section on Impact of SSL setting on cache behavior.

Automatic SSL/TLS (default)

Automatic SSL/TLS leverages advanced methods developed by the SSL/TLS Recommender to select the most secure encryption mode for your website. The Recommender crawls your site using the Cloudflare-SSLDetector user agent, recognized as a trusted bot by Cloudflare, and bypasses robots.txt rules (except those that specifically target it) to ensure accuracy. It downloads content from your origin server over both HTTP and HTTPS, then applies a content similarity algorithm to assess consistency. By understanding your current SSL/TLS encryption mode and evaluating your origin's certification and capabilities, the Recommender can automatically adjust settings to maintain the highest security for your domain.

:::note Automatic SSL/TLS will not change your setting to a less secure encryption mode. For example, if your origin certificate expires, the encryption mode will not change from Full (strict) to Full. You must ensure the validity of your origin SSL/TLS configuration at all times. :::

Automatic upgrades are applied gradually. Automatic SSL/TLS begins to upgrade the domain by starting with just 1% of its traffic. If no issues are found, the new SSL/TLS encryption mode is applied to traffic in 10% increments until 100% of traffic uses the recommended mode. If origin connectivity fails during this process, Cloudflare aborts the upgrade, immediately rolls traffic back to the previous mode, and logs the failure. Once 100% of traffic has been successfully upgraded with no TLS-related errors, the domain's SSL/TLS setting is permanently updated.

Flexible → Full/Strict transitions are handled with extra caution since the origin scheme change (HTTP → HTTPS) alters cache keys. In this case, the ramp-up may proceed more slowly to allow cache warm-up before resuming standard increments.

Additional details

Opt out single zone

If you want to opt a zone out via the API, you can make this API call on or before the grace period expiration date.

<APIRequest path="/zones/{zone_id}/settings/{setting_id}" method="PATCH" json={{ value: "custom", }} parameters={{ setting_id: "ssl_automatic_mode", }} />

Opt out multiple zones

If you wanted to opt out multiple zones:

  1. Create an API token with the following permissions:

    • Zone - Zone - Read
    • Zone - Zone Settings - Read
    • Zone - Zone Settings - Edit
  2. Make a GET request to get a list of zones (you can filter this list by account.id).

    curl 'https://api.cloudflare.com/client/v4/zones?account.id=<ACCOUNT_ID>' \
    --header 'Authorization: Bearer <CF_API_TOKEN>' \
    --header 'Content-Type: application/json'
    
  3. Create a list of zone IDs you want to opt-out with each zone ID on a separate line (newline separate), stored in a file such as zones.txt.

  4. Create a bash script for opt-out-multiple-zones.sh and add the following. Add zones.txt to the same directory or update the path accordingly.

    for zoneID in $(cat zone.txt); do
      printf "Opting out ${zoneID}:\n"
    
      curl --request PATCH \
    		--url https://api.cloudflare.com/client/v4/zones/$zoneID/settings/ssl_automatic_mode \
    		--header 'Authorization: Bearer <CF_API_TOKEN>' \
    		--header 'Content-Type: application/json' \
    		--data '{"value":"custom"}'
    
      printf "\n\n"
    done
    
  5. Open your command line and run:

    bash opt-out-multiple-zones.sh
    

Custom SSL/TLS

To use Custom SSL/TLS, select the custom option (if you prefer to manually set the encryption mode instead of using Automatic SSL/TLS):

Update your encryption mode

Off (no encryption)

import { Render, TabItem, Tabs } from "~/components";

Setting your encryption mode to Off (not recommended) redirects any HTTPS request to plaintext HTTP.

    flowchart LR
        accTitle: No SSL/TLS Encryption
        accDescr: With an encryption mode of Off, your application does not encrypt traffic between the visitor and Cloudflare or between Cloudflare and your server.
        A[Visitor] <--Unencrypted--> B((Cloudflare))<--Unencrypted--> C[(Origin server)]

Use when

Cloudflare does not recommend setting your encryption mode to Off.

Required setup

Limitations

When you set your encryption mode to Off, your application:

Incompatible settings

When you set your SSL/TLS encryption mode to Off, you will not see the options for Always Use HTTPS or Onion Routing.


Strict (SSL-Only Origin Pull)

import { Stream, Render, Tabs, TabItem } from "~/components";

:::note

This method is only available for Enterprise zones. :::

When you set your encryption mode to Strict (SSL-Only Origin Pull), connections to the origin will always be made using SSL/TLS, regardless of the scheme requested by the visitor.

The certificate presented by the origin will be validated the same as with Full (strict) mode.

Use when

You want the most secure configuration available for your origin, you are an Enterprise customer, and you meet the requirements for Full (strict) mode.

Required setup

The setup is generally the same as Full (strict) mode, but you select Strict (SSL-Only Origin Pull) for your encryption mode.

:::note

In addition to Strict (SSL-Only Origin Pull) encryption, you can also set up Authenticated Origin Pulls to ensure all requests to your origin are evaluated before receiving a response.

:::

Process

Limitations

Post-quantum cryptography (PQC)

Post-quantum cryptography (PQC) refers to cryptographic algorithms that have been designed to resist attacks from quantum computers. Cloudflare has been researching and writing about post-quantum since 2017, and is targeting 2029 to be fully post-quantum secure across its entire product suite — refer to Cloudflare targets 2029 for full post-quantum security for the full roadmap.

To protect you against the risk of harvest-now, decrypt-later attacks, and considering all the connections that take place when your website or application is on Cloudflare, we have deployed and are actively expanding the use of post-quantum hybrid key agreement. In parallel, Cloudflare is beginning to deploy post-quantum signatures to protect authentication against future quantum attacks.

Refer to Cloudflare Radar for current statistics on the adoption of PQ encryption in requests to Cloudflare, and visit Cloudflare Radar's browser support check to check if your browser is secured using PQ key agreement.

:::caution[TLS 1.3] Cloudflare post-quantum key agreements are only supported in protocols based on TLS 1.3 (including HTTP/3). :::

Three building blocks of TLS

Before TLS can protect your communications, three cryptographic algorithms have to be agreed on during the TLS handshake:

As explained in our blog post, symmetric ciphers are already post-quantum secure, which means there are two migrations left to occur.

Hybrid key agreement

With TLS 1.3, X25519 - an Elliptic Curve Diffie-Hellman (ECDH) protocol - is the most commonly used algorithm in key agreement. However, its security can be broken by quantum computers using Shor's algorithm.

It is urgent to migrate key agreement to post-quantum algorithms as soon as possible. The objective is to protect against an adversary capable of harvesting today's encrypted communications and storing it until some time in the future when they can gain access to a sufficiently powerful quantum computer to decrypt it.

In response to this, Cloudflare has deployed support for ML-KEM, the post-quantum key agreement selected by the US National Institute of Standards and Technology (NIST). Refer to PQC in Cloudflare products for the current deployment status across products. For a detailed timeline and more background information refer to State of the post-quantum Internet in 2025.

Cloudflare has deployed the following hybrid key agreements:

A hybrid key agreement lays the groundwork as more and more clients adopt post-quantum cryptography, while also maintaining the current security provided by X25519. It is a safer path in case of an unexpected breakthrough that renders all variants of ML-KEM insecure.

Post-quantum signatures

Recent advances in quantum hardware and algorithms have accelerated the timeline on which a cryptographically relevant quantum computer might exist, which in turn elevates the priority of migrating authentication (signatures) to post-quantum algorithms. Refer to Cloudflare targets 2029 for full post-quantum security for context.

Cloudflare has deployed support for ML-DSA, the post-quantum digital signature algorithm selected by NIST (FIPS 204). Today this support covers authentication on the connection between Cloudflare and your origin server (see PQC to your origin). Post-quantum authentication on the connection from the visitor to Cloudflare's edge and for internal Cloudflare connections is still under development. Refer to PQC in Cloudflare products for the products that support ML-DSA today.

For background on the post-quantum signature landscape, refer to A look at the latest post-quantum signature standardization candidates.

Three connections in the life of a request

flowchart LR
        accTitle: Three connections - from visitor to Cloudflare to origin server
        accDescr: Diagram showing connections for an uncached request.
        A[Visitor]
        subgraph Cloudflare
        X[(Cloudflare <br />service A)]
				B[(Cloudflare <br />service B)]
        end
        C[(Origin server)]

        A --1--> X
				X --2--> B
        B --3--> C

1. Visitor to Cloudflare

As of October 2022, all websites and APIs served through Cloudflare over TLS 1.3 support post-quantum hybrid key agreement. However, the connection is only post-quantum secured if the client also supports PQC.

Refer to Post-quantum cryptography support for a list of browsers and other clients that are compatible with hybrid key agreements.

2. Internal connections

As announced in September 2023, most internal connections for Cloudflare's products and systems have been upgraded to use PQC.

3. Cloudflare to your origin

Finally, Cloudflare also supports hybrid key agreements when connecting to origins. In this case, post-quantum secured connections will depend on the origin servers also supporting PQC. Customers can also configure connections to origin servers via PQ Cloudflare Tunnel.

Refer to Post-quantum cryptography between Cloudflare and origin servers for details.

Protect corporate network traffic

With Zero Trust, Cloudflare allows organizations to upgrade their sensitive network traffic to PQC without the hassle of individually upgrading each and every corporate application, system, or network connection. This includes post-quantum Cloudflare IPsec tunnels with both the Cloudflare One Appliance and validated third-party devices. Cisco and Fortinet are the first third-party vendors validated to interoperate with Cloudflare IPsec for post-quantum key agreement — refer to Tested third-party vendor interoperability for the current list. For details on the Cloudflare One configurations, refer to Post-quantum cryptography in Cloudflare's Zero Trust platform.

Post-quantum cryptography in Cloudflare One

Cloudflare One replaces legacy corporate security perimeters with Cloudflare's global network, making access to the Internet and to corporate resources faster and safer for teams around the world.

Organizations can obtain end-to-end post-quantum encryption of their private network traffic by sending it over Cloudflare One's post-quantum on-ramps and off-ramps. This protects traffic against harvest-now, decrypt-later attacks even if the individual applications are not yet upgraded to post-quantum encryption.

Post-quantum encryption is offered in all major Cloudflare One network configurations, including the following on-ramps:

And off-ramps:

For traffic that egresses to the public Internet, Cloudflare Gateway also provides post-quantum encryption as a Secure Web Gateway (SWG).

These on-ramps and off-ramps all use hybrid post-quantum key agreement.

Overview diagram of post-quantum Cloudflare One network configurations showing on-ramps and off-ramps

The sample configurations below illustrate how Cloudflare One's post-quantum on-ramps and off-ramps fit together for several common use cases. For the broader status of post-quantum support across all Cloudflare products and connections, refer to PQC in Cloudflare products.

Browser to self-hosted application {/* agentless-cloudflare-access */}

A common configuration is browser access to a self-hosted application that is exposed to Cloudflare's network via a Cloudflare Tunnel. This is often combined with Cloudflare Access for identity-based policy enforcement; refer to the agentless access learning path for guidance.

Even if the application itself has not yet migrated to post-quantum cryptography, traffic to it will be protected against harvest-now, decrypt-later attacks.

Diagram of how post-quantum cryptography works for browser-based access to a self-hosted application via Cloudflare Tunnel.

Here is how it works today:

1. Connection via browser

As long as the end user uses a modern web browser that supports post-quantum key agreement, the connection from the device to Cloudflare's network is secured via TLS 1.3 with post-quantum key agreement.

2. Within Cloudflare's global network

If the user and origin server are geographically distant, then the user's traffic will enter Cloudflare's global network in one geographic location (such as Frankfurt), and exit at another (such as San Francisco). As this traffic moves from one data center to another inside Cloudflare's global network, these hops through the network are secured via TLS 1.3 with post-quantum key agreement.

3. Cloudflare Tunnel

Customers establish a Cloudflare Tunnel from their data center or public cloud — where their corporate web application is hosted — to Cloudflare's network. This tunnel is secured using TLS 1.3 with post-quantum key agreement.

This configuration provides end-to-end post-quantum protection for browser access to corporate HTTPS applications without requiring customers to upgrade the security of the applications themselves.

Cloudflare One Client

Cloudflare One Client (formerly WARP) tunnels traffic from the end-user device to Cloudflare's global network. The following is an example network configuration with a Cloudflare One Client on-ramp and a Cloudflare Tunnel off-ramp.

Diagram of post-quantum network configuration using Cloudflare One Client on-ramp and Cloudflare Tunnel off-ramp

Note: Labels in this image may reflect a previous product name.

1. Connection via Cloudflare One Client

The Cloudflare One Client uses the MASQUE protocol to connect from the device to Cloudflare's global network, using TLS 1.3 with hybrid ML-KEM.

2. Within Cloudflare's global network

The traffic then travels across Cloudflare's global network over TLS 1.3 with hybrid ML-KEM.

3. Cloudflare Tunnel

Cloudflare Tunnel supports post-quantum key agreement.

With this network configuration, traffic is encapsulated in tunnels protected with post-quantum encryption without requiring individual upgrades of networks or applications. This provides comprehensive protection for any protocol that can be sent through these tunnels, not just for HTTPS.

Cloudflare IPsec

The following is a sample network configuration that uses the Cloudflare One Client on-ramp to connect an end-user device to a server behind a Cloudflare One Appliance off-ramp. Traffic to the server is protected by post-quantum cryptography as it travels over the public Internet, even if the server itself does not support post-quantum cryptography.

Diagram of post-quantum network configuration using Cloudflare One Client on-ramp to Cloudflare One Appliance off-ramp

1. Connection via Cloudflare One Client

The Cloudflare One Client uses the MASQUE protocol, as described in the Cloudflare One Client section above.

2. Within Cloudflare's global network

The traffic then travels across Cloudflare's global network over TLS 1.3 with hybrid ML-KEM.

3. Cloudflare IPsec with Cloudflare One Appliance

Traffic leaves the Cloudflare network over a post-quantum Cloudflare IPsec link that is terminated at a Cloudflare One Appliance. The Cloudflare One Appliance uses a non-IKE keying protocol built into the control plane, secured with TLS, that establishes the keys used to encrypt dataplane traffic in the IPsec ESP protocol. From Appliance version 2026.2.0, the control plane establishes keys over TLS 1.3 protected with hybrid ML-KEM.

Cloudflare IPsec with third-party devices

Cloudflare IPsec also supports post-quantum key agreement with compatible third-party network devices using standard IKEv2. This extends post-quantum protection to organizations that connect their own routers and firewalls to Cloudflare's global network instead of using the Cloudflare One Appliance.

The hybrid key agreement is negotiated using ML-KEM as an additional Key Exchange to classical Diffie-Hellman during the IKEv2 handshake, as defined in RFC 9370 and draft-ietf-ipsecme-ikev2-mlkem. For the list of validated third-party platforms and their supported parameters, refer to Tested third-party vendor interoperability.

Cloudflare also supports downgrade protection for IPsec tunnels via the IKE_SA_INIT_FULL_TRANSCRIPT_AUTH extension. Both the initiator and Cloudflare (responder) must support the extension for protection to be effective. Refer to Downgrade protection.

Secure Web Gateway

A secure web gateway (SWG) is used to secure access to third-party websites on the public Internet by intercepting and inspecting TLS traffic.

Cloudflare Gateway supports post-quantum cryptography for HTTPS traffic. As long as the third-party website that is being inspected supports post-quantum key agreement, Cloudflare's SWG also supports post-quantum key agreement.

Cloudflare Gateway's HTTPS filtering feature involves two post-quantum connections, as follows:

1. Connection from the client to Gateway

The client reaches Gateway through one of the post-quantum on-ramps: the Cloudflare One Client or a Cloudflare IPsec tunnel. These on-ramps carry the client's traffic to Gateway with post-quantum key agreement.

2. Connection from Gateway to the origin server

A TLS connection is initiated from a data center in Cloudflare's network to the origin server, which is typically controlled by a third party. The connection from Cloudflare's SWG supports post-quantum key agreement, as long as the third-party origin server also supports post-quantum key agreement. You can test this out by using https://pq.cloudflareresearch.com/ as your third-party origin server.

PQC in Cloudflare products

Cloudflare is targeting 2029 to be fully post-quantum secure across its entire product suite.

This page shows the status of the migration. Each section below groups Cloudflare products by the underlying secure communication channel. Once a channel supports PQC, every product built on top inherits PQC support.

Each section captures the classes of post-quantum algorithms deployed in the secure communication channel: key agreement (sometimes called post-quantum encryption, which protects against harvest-now, decrypt-later attacks) and signatures (sometimes called post-quantum authentication, which protects live systems against unauthorized access by quantum adversaries after Q-Day).

A Cloudflare-side ✅ entry only delivers end-to-end post-quantum protection when the party on the other side of the connection also supports the same post-quantum algorithms. Refer to PQC support for the list of browsers, libraries, and servers that support the algorithms Cloudflare has deployed.

For an end-to-end walkthrough of how Cloudflare One on-ramps and off-ramps fit together, refer to PQC and Cloudflare One.

Visitor to Cloudflare

Inbound TLS 1.3 (including QUIC) from end-user clients to Cloudflare's edge.

Protection Status
Key agreement ✅ X25519MLKEM768
Signatures 📝 Planned via Merkle Tree Certificates

Reference: PQC for all websites and APIs.

Products covered: any proxied hostname or HTTPS application behind Cloudflare, including:

Customers can measure per-zone post-quantum key agreement adoption on their inbound traffic using the ClientTLSKeyExchangeGroup field in the http_requests Logpush dataset, which is also queryable in Log Explorer.

This section only covers the inbound TLS connection from the end-user client to Cloudflare's edge. When a Worker fetches data from a backend storage service (D1, KV, Durable Objects, R2, Workers AI, Hyperdrive, and similar), that connection is governed by the Cloudflare internal network section. When a Worker calls out to a third-party origin via fetch(), it is governed by the Cloudflare to origin section.

Cloudflare internal network

Service-to-service TLS connections between Cloudflare data centers and internal services.

Protection Status
Key agreement 🚧 X25519MLKEM768
Signatures Not yet

Reference: PQC generally available, Roadmap.

Most internal connections have been migrated to X25519MLKEM768. A long tail of services is still in the process of being upgraded.

Cloudflare to origin

Outbound TLS 1.3 connections from Cloudflare's edge to customer origin servers.

Protection Status
Key agreement ✅ X25519MLKEM768
Signatures ✅ ML-DSA via Authenticated Origin Pulls and Custom Origin Trust Store

Reference: PQC to your origin.

Products covered: any Cloudflare-proxied zone's origin pull, and the egress leg of Cloudflare Gateway (SWG, HTTPS inspection) when Gateway fetches third-party origin content on behalf of the client. Gateway's post-quantum support on this leg is independent of which on-ramp the client uses to reach Cloudflare.

:::note If your origin server does not yet support PQC, you can onboard it to Cloudflare's network with a PQC connection by putting it behind Cloudflare Tunnel. :::

Cloudflare Tunnel

Outbound TLS 1.3 tunnel from cloudflared on a customer origin to Cloudflare's global network.

Protection Status
Key agreement ✅ X25519MLKEM768
Signatures Not yet

Reference: PQ Cloudflare Tunnel, PQC and Cloudflare One.

Products covered: Workers VPC private-network access and any Cloudflare One off-ramp that egresses via cloudflared (for example, Cloudflare Access self-hosted applications).

Cloudflare One

The sections below cover the connections and services that make up Cloudflare One. For an end-to-end walkthrough of how on-ramps and off-ramps fit together, refer to PQC and Cloudflare One.

Cloudflare One Client

MASQUE tunnel (TLS 1.3) from an end-user device to Cloudflare's global network, established by the Cloudflare One Client (formerly WARP).

Protection Status
Key agreement ✅ X25519MLKEM768
Signatures Not yet

Reference: PQC and Cloudflare One: Cloudflare One Client.

This connection also serves as a post-quantum on-ramp for traffic that traverses Cloudflare Gateway.

Cloudflare Mesh

Cloudflare Mesh provides private IP connectivity between devices and servers using the Cloudflare One Client on each Mesh node and client device.

Mesh inherits its post-quantum protection from the Cloudflare One Client connection, which is used as both the on-ramp and the off-ramp for Mesh traffic.

Cloudflare Gateway

Cloudflare Gateway is a Secure Web Gateway that runs on Cloudflare's edge and filters HTTPS traffic egressing to the public Internet. Gateway has no client-side component; clients reach Gateway via one of several post-quantum on-ramps:

The egress leg from Gateway to third-party origin servers is covered by Cloudflare to origin and is independent of the on-ramp.

Reference: PQC and Cloudflare One: Secure Web Gateway.

Cloudflare IPsec

IKEv2 key exchange for IPsec tunnels between third-party branch connectors and Cloudflare's global network.

Protection Status
Key agreement ✅ ML-KEM-768/1024 + DH Group 20 (P-384) in IKEv2
Downgrade protection 🚧 IKE_SA_INIT_FULL_TRANSCRIPT_AUTH
Signatures Not yet

Reference: PQC SASE, GRE and IPsec tunnels, draft-ietf-ipsecme-ikev2-mlkem, draft-ietf-ipsecme-ikev2-downgrade-prevention.

The IPsec ESP dataplane can alternatively be keyed using the Cloudflare One Appliance control plane instead of IKEv2.

Cloudflare One Appliance

TLS 1.3 control-plane connection used by the Cloudflare One Appliance (formerly Magic WAN Connector) to establish keys for its IPsec ESP dataplane tunnels.

Protection Status
Key agreement ✅ X25519MLKEM768
Signatures Not yet

Reference: PQC SASE, Cloudflare One Appliance, PQC and Cloudflare One.

Cloudflare Email Security

Post-quantum protection applies to inbound and outbound TLS 1.3 SMTP connections between Cloudflare Email Security MX deployments and third-party mail servers:

Protection Status
Key agreement ✅ X25519MLKEM768
Signatures Not yet

Reference: Email Security, MX/Inline deployment.

Post-quantum key agreement is negotiated automatically when the remote SMTP peer advertises support (for example, Google Workspace). Senders and receivers that do not yet advertise post-quantum key agreement continue to connect with classical key exchange.

Contributing

This listing is maintained alongside the rest of the Cloudflare SSL/TLS documentation. If you spot an inaccuracy or have an update after a product announcement, contributions are welcome.

PQC support

The sections below summarize third-party software support for the post-quantum algorithms Cloudflare has deployed, organized by software category. Contributions to keep the listing up-to-date are welcome.

Two classes of algorithm are tracked:

:::caution The listings below are for reference only. Responsibility for third-party software lies with their respective maintainers. Use them at your own discretion. :::

Browsers

Browsers are grouped by the underlying rendering engine and TLS stack. Browsers sharing an engine generally share the same post-quantum support, but derivative browsers can lag the upstream engine or disable post-quantum features by policy. Verify behavior in the specific browser version you care about before assuming derivative support. Cloudflare Radar's browser support check is a quick way to confirm whether a given browser negotiates post-quantum key agreement with Cloudflare.

Chromium-based (BoringSSL)

Brave

Chrome

Chrome is not planning to add standard X.509 post-quantum certificates to the public Chrome Root Store. Instead, Chrome is developing MTCs in the IETF PLANTS working group, currently in a feasibility study phase with Cloudflare.

Edge

Opera

Gecko-based (Firefox / NSS)

Firefox

For QUIC/HTTP3, Firefox 135+ (Desktop).

Tor Browser

Based on Firefox ESR with additional hardening.

WebKit-based (Safari)

Safari

System-wide in iOS 26, macOS Tahoe 26, and other Apple operating systems.

Libraries

This section splits into the foundational native libraries (written in C/C++) and the language bindings and higher-level libraries that build on top of them.

Native libraries

AWS-LC

ML-KEM-512/768/1024 and hybrids X25519MLKEM768, SecP256r1MLKEM768, SecP384r1MLKEM1024; ML-DSA-44/65/87.

BoringSSL

ML-DSA-44/65/87.

Botan C++

ML-DSA-44/65/87.

GnuTLS

Hybrids X25519MLKEM768 and SecP256r1MLKEM768 from 3.8.8+; SecP384r1MLKEM1024 added in 3.8.9+. ML-DSA-44/65/87.

OpenSSL

Hybrid X25519MLKEM768 in 3.5.0+; SecP256r1MLKEM768 and curveSM2MLKEM768 added in 3.6.0+. ML-DSA-44/65/87.

Open Quantum Safe

Reference implementations, not recommended for production.

s2n-tls

AWS's open-source TLS implementation built on AWS-LC.

Language bindings and higher-level libraries

aws-lc-rs (Rust)

Rust bindings around AWS-LC; underlies rustls-post-quantum's ML-DSA support. ML-KEM via aws-lc-rs::kem; ML-DSA-44/65/87 via unstable::signature.

CIRCL (Cloudflare)

Pure-Go cryptographic primitives library. ML-KEM-512/768/1024 and ML-DSA-44/65/87.

Go

Cloudflare's fork of Go also supports key agreement via CIRCL.

Java (OpenJDK)

Node.js

Uses bundled OpenSSL 3.5. ML-DSA-44/65/87.

RustCrypto (Rust)

Pure-Rust crates, independent of AWS-LC. ML-DSA-44/65/87.

rustls (Rust)

TLS library built on top of rustls-post-quantum.

rustls-post-quantum (Rust)

Extension crate for rustls that provides post-quantum algorithms using aws-lc-rs under the hood.

Zig

Servers

Caddy

NGINX

rpxy

Traefik

Post-quantum between Cloudflare and origin servers

import { Example } from "~/components";

This page covers post-quantum cryptography on the TLS connection between Cloudflare's edge and your origin server. Cloudflare supports both post-quantum key agreement (X25519MLKEM768) and post-quantum signatures (ML-DSA via Authenticated Origin Pulls and Custom Origin Trust Store) on this connection.

If you would prefer to connect your origin to Cloudflare without managing certificates on a publicly exposed TLS endpoint, Cloudflare Tunnel is another option for post-quantum origin connections. Cloudflare Tunnel uses post-quantum key agreement on the TLS connection between cloudflared and Cloudflare's network. Post-quantum signatures are not yet used for authentication on that path.

Post-quantum key agreement

As explained in About PQC, Cloudflare has deployed support for hybrid key agreements, which includes both the most common key agreement for TLS 1.3, X25519, and the post-quantum secure ML-KEM.

With X25519, the ClientHello almost always fits within one network packet. However, with the addition of ML-KEM, the ClientHello is typically split across two packets.

This poses a question of how the origin servers - as well as other middleboxes (routers, load balancers, etc) - will handle this change in behavior. Although allowed by the TLS 1.3 standard (RFC 8446), a split ClientHello risks not being handled well due to protocol ossification and implementation bugs. Refer to our blog post for details.

ClientHello from Cloudflare

Cloudflare uses automatic key exchange to learn which key agreements a zone's origin servers prefer. Cloudflare applies one preference across the zone. When the selected preference is X25519MLKEM768, Cloudflare sends that key share in the initial ClientHello to allow for faster connection establishment.

Cloudflare continues to advertise other allowed key agreements. If an origin requires another key share, it can use a HelloRetryRequest to request one. The retry adds one network round trip but does not break the connection.

Set up

Cloudflare zone settings

Automatic key exchange is on for all existing zones and on by default for new zones. When an origin supports both classical and post-quantum options, Cloudflare prefers post-quantum key agreement.

Use Automatic key exchange to control scanning and preferred key share selection. Compliance requirements apply only to TLS 1.3 connections.

The Origin Post-Quantum Encryption API remains available. Requests to this API are no-ops and do not change a zone's post-quantum key agreement behavior. Cloudflare plans to deprecate this API, but a deprecation date has not been established.

Origin server

To make sure that your origin server prefers the post-quantum key agreement, use the bssl tool of BoringSSL:

```bash bssl client -connect :443 -curves X25519MLKEM768 ```

Verify that the ECDHE curve in the handshake output indicates X25519MLKEM768.

Post-quantum signatures

Since mid-2026, Cloudflare supports ML-DSA post-quantum signatures in two origin-facing features:

Both can be used independently or together. Using them together lets you establish end-to-end post-quantum authentication between Cloudflare's edge and your origin server, in addition to post-quantum key agreement.

Requirements

:::note ML-DSA private keys must be provided in the seed-only encoding when uploaded to Cloudflare. The expanded-key encoding is currently rejected by the upload endpoints. :::

Generate an ML-DSA certificate authority and leaf certificate

The following commands create a private certificate authority and a leaf certificate that chains to it, using ML-DSA-44. Repeat once for an AOP client certificate, and once for a COTS server-facing certificate if you manage that side too.

# Private ML-DSA-44 CA (30-year validity)
openssl genpkey \
  -algorithm mldsa44 \
  -provparam ml-dsa.output_formats=seed-only \
  -out ca.key
openssl req -new -x509 \
  -key ca.key \
  -out ca.crt \
  -days 10950 \
  -subj "/CN=ML-DSA Origin CA"

# Leaf certificate signed by the CA (15-year validity)
openssl genpkey \
  -algorithm mldsa44 \
  -provparam ml-dsa.output_formats=seed-only \
  -out leaf.key
openssl req -new \
  -key leaf.key \
  -out leaf.csr \
  -subj "/CN=origin.example.com" \
  -addext basicConstraints=CA:FALSE \
  -addext keyUsage=digitalSignature \
  -addext subjectAltName=DNS:origin.example.com
openssl x509 -req \
  -in leaf.csr \
  -CA ca.crt -CAkey ca.key \
  -CAcreateserial \
  -out leaf.crt \
  -days 5475 \
  -copy_extensions copy

The -provparam ml-dsa.output_formats=seed-only flag is required so that the private key is written in the FIPS 204 seed form rather than as the expanded private key. This is the only form Cloudflare currently accepts on upload.

Verify the generated cert:

openssl x509 -in leaf.crt -noout -subject -issuer -dates -ext subjectAltName

Set up Authenticated Origin Pulls with an ML-DSA client certificate

ML-DSA client certificates are supported with both zone-level and per-hostname AOP. Generate an ML-DSA CA and leaf cert as described in Generate an ML-DSA certificate authority and leaf certificate, then follow the setup guide for the scope you are configuring. The global AOP scope uses a Cloudflare-provided certificate and is not configurable.

On the origin server side, install the ML-DSA CA certificate (the ca.crt file generated earlier) so that your TLS server can verify the client certificate that Cloudflare presents. For nginx, this looks like:

ssl_client_certificate /etc/ssl/cloudflare-aop-ca.crt;
ssl_verify_client      on;

Refer to the AOP setup guide for origin servers for complete origin-side configuration.

Set up Custom Origin Trust Store with an ML-DSA CA

Upload the ML-DSA CA certificate (the ca.crt file generated earlier) as a Custom Origin Trust Store entry. Cloudflare will then trust any origin server certificate that chains to that CA under Full (strict) encryption mode.

:::caution Uploading a Custom Origin Trust Store CA replaces the default publicly trusted CAs for the zone. Cloudflare will no longer trust origin certificates signed by public CAs on that zone while the COTS entry is in place. Refer to Custom Origin Trust Store — Limitations for details. :::

On the origin server side, present the ML-DSA leaf certificate and its private key as the TLS server cert:

ssl_certificate     /etc/ssl/origin-mldsa.pem;
ssl_certificate_key /etc/ssl/origin-mldsa.key;
ssl_protocols       TLSv1.3;

Verify end-to-end

Once AOP and COTS are configured, you can verify the post-quantum origin handshake from a host that has ML-DSA support. For example, from a machine with OpenSSL 3.5.0 or later, connect directly to your origin and confirm the handshake uses ML-DSA:

openssl s_client \
  -connect origin.example.com:443 \
  -servername origin.example.com \
  -CAfile ca.crt \
  -cert leaf.crt \
  -key leaf.key \
  -brief

The output should show Signature type: mldsa44 and Negotiated TLS1.3 group: X25519MLKEM768.

Avoid downgrades

Presenting an ML-DSA certificate on the authenticating side is not enough on its own. To actually gain post-quantum authentication, the verifying side must reject classical (non-post-quantum) certificates. If the verifier still accepts a classical certificate, an attacker who compromises that classical key can impersonate the peer with an on-path attack — a downgrade that negates the post-quantum protection.

Browser compatibility

Cloudflare attempts to provide compatibility for as wide a range of user agents (browsers, API clients, etc.) as possible. However, the specific set of supported clients can vary depending on the different SSL/TLS certificate types, your visitor's browser version, and the certificate authority (CA) that issues the certificate.

Universal SSL

Cloudflare Universal SSL only supports browsers and API clients that use the Server Name Indication (SNI) extension to the TLS protocol.

Also, for zones on Free plan, Universal SSL is only compatible with browsers that support Elliptic Curve Digital Signature Algorithm (ECDSA).

Paid plans have additional compatibility, also supporting RSA algorithm.

Other certificate types

Refer to Certificate authorities for a detailed list of Cloudflare SSL/TLS offerings, the different algorithms available, and browser compatibility for each CA.

Non-SNI support

Although SNI extensions to the TLS protocol were standardized in 2003, some browsers and operating systems only implemented this extension when TLS 1.1 was released in 2006 (or 2011 for mobile browsers). If your visitors use devices that have not been updated since 2011, they may not have SNI support.

To support non-SNI requests, you can:

HTTPS records

HTTPS Service (HTTPS) records allow you to provide a client with information about how it should connect to a server upfront, without the need of an initial plaintext HTTP connection.

If your domain has HTTP/2 or HTTP/3 enabled, proxied DNS records, and is also using Universal SSL, Cloudflare automatically generates HTTPS records on the fly, to advertise to clients how they should connect to your server.

:::caution[Universal SSL required for automatic HTTPS records] Disabling Universal SSL will prevent automatic HTTPS record generation for proxied hostnames, even if you have Advanced Certificates or custom certificates configured. This is because automatic HTTPS record generation is tied specifically to the Universal SSL feature.

If you need HTTPS records without Universal SSL, you can manually add them, but only if all records with the same name are DNS-only (grey cloud). Refer to SVCB and HTTPS records for details and examples. :::

OCSP and HTTP versions

Cloudflare's OCSP implementation uses HTTP/1.1 by default for plain HTTP connections.

For HTTPS connections, the client automatically attempts to use HTTP/2 if the server supports it through the TLS ALPN (Application-Layer Protocol Negotiation) extension. If HTTP/2 is not available or supported by the server, it will fall back to HTTP/1.1.

Certificate and hostname priority

import { GlossaryTooltip } from "~/components";

When a new certificate is created, Cloudflare first deploys the certificate and then serves it.


Certificate deployment

For any given hostname, Cloudflare uses the following order to determine which certificate (and associated TLS settings) to apply to that hostname:

  1. Hostname specificity: A specific subdomain certificate (www.example.com) would take precedence over a wildcard certificate (*.example.com) for requests to www.example.com.

  2. Zone specificity: A specific subdomain certificate (www.example.com) would take precedence over a custom hostname certificate if the domain is active as a zone on Cloudflare.

  3. Certificate priority: If the hostname is the same, certain types of certificates take precedence over others.

    Priority Certificate Type
    1 Keyless SSL
    2 Custom Legacy
    3 Custom Modern
    4 Custom Hostname (Cloudflare for SaaS)
    5 Advanced
    6 Advanced - Total TLS
    7 Universal
  4. Certificate expiration: The most recently ordered certificate takes precedence unless a certificate deletion has occurred. If and when a certificate is deleted, the certificate with the latest expiration date is deployed.

:::note In this case, when the certificate with the closest expiration date is renewed, it will then become the one with the latest expiration date and get presented. :::


Certificate presentation

Cloudflare uses the following order to determine the certificate and settings used during a TLS handshake:

  1. SNI match: Certificates and settings that match the SNI hostname exactly take precedence.
  2. SNI wildcard match: If there is not an exact match between the hostname and SNI hostname, Cloudflare uses certificates and settings that match an SNI wildcard.
  3. IP address: If no SNI is presented, Cloudflare uses certificate based on the IP address (the hostname can support TLS handshakes made without SNI).

Hostname priority

When multiple proxied DNS records exist for a hostname, in multiple zones — usually due to Cloudflare for SaaS — only one record will control the zone settings and associated origin server.

Cloudflare determines this priority in the following order, assuming each record exists and is proxied (orange-clouded):

  1. Exact hostname match:

    1. New custom hostname (belonging to a SaaS provider)
    2. Legacy custom hostname (belonging to a SaaS provider)
    3. DNS (belonging to the logical DNS zone)
  2. Wildcard hostname match:

    1. DNS (belonging to the logical DNS zone)
    2. New custom hostname (belonging to a SaaS provider)

If a hostname resource record is not proxied (gray-clouded) for a zone on Cloudflare, that zone's settings are not applied and any settings configured at the associated origin are applied instead. This origin could be another zone on Cloudflare or any other server.

Example scenarios

Scenario 1

Customer1 uses Cloudflare as authoritative DNS for the zone shop.example.com. Customer2 is a SaaS provider that creates and successfully verifies the new custom hostname shop.example.com. Afterward, traffic starts routing over Customer2's zone:

Scenario 2

A customer has a proxied DNS record for their domain. The customer's zone on Cloudflare is using a Free plan.

This customer is also using a SaaS provider that uses Cloudflare for SaaS. The SaaS provider is using a Cloudflare Enterprise plan.

If the provider is using a wildcard custom hostname, then the original customer's plan limits will take precedence over the provider's plan limits (Cloudflare will treat the zone as a Free zone). To apply the Enterprise limits through Cloudflare for SaaS, the original customer's zone would need to either use a DNS-only record or the SaaS provider would need to use an exact hostname match.

Certificate authorities

import { Render } from "~/components";

For publicly trusted certificates, Cloudflare partners with different certificate authorities (CAs). Refer to this page to check what CAs are used for each Cloudflare offering and for more details about the CAs features, limitations, and browser compatibility.

Availability per certificate type and encryption algorithm

Certificate Algorithm Let's Encrypt Google Trust Services SSL.com Sectigo
Universal ECDSA


RSA
(Paid plans only)
✅


✅
✅


✅
✅


✅
N/A


N/A
Advanced ECDSA


RSA
✅


✅
✅


✅
✅


✅

N/A


N/A
Total TLS ECDSA


RSA
✅


✅
✅


✅
✅


✅

N/A


N/A
SSL for SaaS ECDSA


RSA
✅


✅
✅


✅
✅


✅

N/A


N/A
Backup ECDSA

RSA
✅

✅
✅

✅
✅

✅
✅

✅

Features, limitations, and browser compatibility

:::caution[Universal SSL] For Universal certificates, Cloudflare controls the validity periods and certificate authorities (CAs), making sure that renewal always occur. For details, refer to Universal SSL. :::


Let's Encrypt

Limitations

Browser compatibility

:::caution[Warning]

This section summarizes commonly requested client support information. For the complete and most up-to-date certificate compatibility, refer to Let's Encrypt documentation.

:::

The main determining factor for whether a platform can validate Let's Encrypt certificates is whether that platform trusts the self-signed ISRG Root X1 certificate. As Let's Encrypt announced a change in its chain of trust in 2024, older devices (for example Android 7.0 and earlier) that only trust the cross-signed version of the ISRG Root X1 are no longer compatible.

You can find the full list of supported clients in the Let's Encrypt documentation. Older versions of Android and Java clients might not be compatible with Let's Encrypt certificates.

Other resources

Let's Encrypt Root CAs: For checking compatibility between chain and client. As explained in Certificate pinning, you should not use this list for pinning against.


Google Trust Services

Browser compatibility (most compatible)

:::caution[Warning]

This section summarizes commonly requested client support information. For the complete and most up-to-date certificate compatibility, refer to Google Trust Services documentation.

:::

By cross-signing with a GlobalSign root CA that has been installed in client devices for more than 20 years, Google Trust Services can ensure optimal support across a wide range of devices.

Currently trusted by Microsoft, Mozilla, Safari, Cisco, Oracle Java, and Qihoo’s 360 browser, all browsers or operating systems that depend on these root programs are covered.

You can use the root CAs list for checking compatibility between chain and client but, as explained in Certificate pinning, you should not use this list for pinning against.


SSL.com

Limitations

SSL.com DCV tokens are specific for RSA certificates and ECDSA certificates. This means that, for cases where you have to manually perform DCV, you will have to place two validation tokens per certificate order. To avoid management overhead, consider using a full setup, or setting up Delegated DCV.

Browser compatibility

:::caution[Warning]

This section summarizes commonly requested client support information. For the complete and most up-to-date certificate compatibility, refer to SSL.com documentation.

:::

SSL.com is highly compatible, being accepted by over 99.9% of browsers, tablets, and mobile devices.

SSL.com certificates are cross-signed with Certum and the CA that cross-signs intermediates is from 2004.

Other resources

Acceptable top level domains (TLDs) and current restrictions


Sectigo

Browser compatibility

Refer to Sectigo documentation.


CAA records


If you are using Cloudflare as your DNS provider, then the CAA records will be added on your behalf. If you need to add CAA records, refer to Add CAA records.

The following table lists the CAA record content for each CA:

Certificate authority CAA record content
Let's Encrypt letsencrypt.org
Google Trust Services pki.goog; cansignhttpexchanges=yes
SSL.com ssl.com
Sectigo sectigo.com

[^1]: A payment gateway used with some ecommerce plugins.

Certificate pinning

import { GlossaryTooltip } from "~/components";

Cloudflare does not support HTTP public key pinning (HPKP) for universal, advanced, or custom hostname certificates.

Cloudflare regularly rotates the edge certificates provisioned for your domain. If HPKP was enabled, your domain would go offline each time a certificate rotates because the new certificate would not match the pinned key. Additionally, industry experts discourage using HPKP. For a detailed overview, refer to the Cloudflare blog post on why certificate pinning is outdated.

The problem HPKP tries to solve is preventing certificate misissuance. A safer way to detect misissuance without risking downtime is Certificate Transparency Monitoring, which alerts you when a certificate is issued for your domain.

If you must pin certificates

If your use case requires certificate pinning, the only advisable approach is to upload a custom certificate to Cloudflare and pin to that certificate. Because you control the certificate lifecycle — including renewal timing, CA selection, and key material — you can ensure pin continuity. However, pinning still carries outage risk: if a renewal deploys a new key, clients pinned to the old key will fail TLS. If you need pin continuity, you must intentionally reuse the same key material during renewal. Test renewed certificates in the staging environment before production.

Select the user-defined bundle method so that you control exactly which CA, intermediate, and leaf certificate are served.

[^1]: Key pinning allows a host to instruct a browser to only accept certain public keys when communicating with it for a given period of time.

Rotate ACM certificate packs

import { DashButton, TabItem, Tabs } from "~/components";

Advanced Certificate Manager (ACM) certificate packs cannot be updated in place. To replace an existing pack - for example, to change the certificate authority, add hostnames, or change validation method - you create a new pack, wait for it to reach Active status, and then delete the old one.

The key principle is to ensure the new certificate pack reaches Active before removing the old one. This avoids any gap in coverage and means there is no downtime for your users.


1. Create the new certificate pack

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. Select Order Advanced Certificate.

  3. Configure the new certificate pack with the desired hostnames, certificate authority, and validation method.

  4. Select Save.

Use the Order Certificate Pack endpoint to create the new pack.

Add a new cloudflare_certificate_pack resource to your Terraform configuration and apply it. Refer to the Terraform-specific notes below before proceeding.

2. Wait for Active status

After ordering, the new certificate pack moves through several intermediate states before it is ready to serve traffic:

  1. Initializing
  2. Pending Validation
  3. Pending Issuance
  4. Pending Deployment
  5. Active

Do not delete the old certificate pack until the new one reaches Active. Refer to Certificate statuses for a description of each stage.

Monitor progress on the Edge Certificates page in the dashboard, or poll the Get Certificate Pack API endpoint.

For zones using Cloudflare as authoritative DNS (full setup), most validations complete within minutes. For partial (CNAME) setups, you will need to place DCV tokens manually - refer to DCV methods for details. DCV tokens expire if not satisfied within their validity window (7 days for Let's Encrypt, 14 days for Google Trust Services and SSL.com).

3. Delete the old certificate pack

Once the new pack is Active, it is safe to delete the old one.

  1. In the Cloudflare dashboard, go to the Edge Certificates page.

  2. Select the old certificate pack.

  3. Select Delete Certificate.

Use the Delete Certificate Pack endpoint.

Remove the old cloudflare_certificate_pack resource from your Terraform configuration and apply. Refer to the Terraform-specific notes below.

4. Expect a brief Pending Deployment state

After the old pack is deleted, the remaining certificate may briefly show Pending Deployment before returning to Active. This reflects a normal edge re-evaluation cycle as the global network reconciles the change, and typically resolves within a few minutes with no traffic impact.

If the certificate remains in Pending Deployment for longer than expected, refer to Certificate statuses and contact Cloudflare Support.


Terraform

Certificate packs cannot be updated in place - every attribute of the cloudflare_certificate_pack resource forces a new resource on change. Plan your rotation around this constraint.

:::caution

Importing existing certificate packs into Terraform state is supported but not recommended. If Cloudflare reissues the certificate (for example, on renewal), the resource ID changes and your Terraform state goes out of sync. The recommended pattern is to manage the full lifecycle through Terraform - create, wait for active, then delete - rather than importing existing packs.

:::

Wait for Active automatically

Set wait_for_active_status = true on the new resource to have Terraform block the apply until the certificate pack reaches Active. This removes the need to manually poll the dashboard or API between steps 1 and 3.

  1. Add the new cloudflare_certificate_pack resource with wait_for_active_status = true and run terraform apply. The apply will not complete until the pack is Active.
  2. Remove the old resource from your configuration and run terraform apply to delete it.

For zero-downtime rotation of a single resource (where you cannot have both old and new in state simultaneously), use Terraform's create_before_destroy lifecycle meta-argument.

Refer to the cloudflare_certificate_pack provider documentation for the full resource schema.


Common rotation issues

Let's Encrypt rate limit

Let's Encrypt limits new certificates to five per seven-day window for the same exact set of hostnames. Repeated rotations (for example, during testing or automation loops) can exhaust this limit and block further issuance for up to a week.

If you hit this limit, switch the certificate authority to Google Trust Services or SSL.com or wait for the rate limit window to expire. Refer to Let's Encrypt rate limits for details.

Pack stuck in Pending Validation

If a new pack remains in Pending Validation for more than 15 minutes, check that your DCV method is set up correctly. Refer to Domain Control Validation and Troubleshoot domain control validation.


Distinction from custom certificate replacement

This page covers ACM certificate packs (Cloudflare-managed Domain Validated certificates ordered via Advanced Certificate Manager).

If you are using a custom certificate (a certificate you supplied), Cloudflare provides an in-place Replace SSL certificate and key flow that handles the rotation without requiring you to manage two packs. Refer to Manage custom certificates.

Certificate statuses

Certificates statuses show which stage of the issuance process each certificate is in.

New certificates

When you order a new certificate, either an edge certificate or a certificate used for a custom hostname, its status will move through various stages as it progresses to Cloudflare's global network:

  1. Initializing
  2. Pending Validation
  3. Pending Issuance
  4. Pending Deployment
  5. Active

Once you issue a certificate, it should be in Pending Validation, but change to Active after the validation is completed. If you see any errors, you or your customer may need to take additional actions to validate the certificate.

If you deactivate a certificate, it will become a Deactivating and then an Inactive status.

Certificate replacement

When replacing a certificate, you may note a Pending Cleanup status. Old certificates are not deleted until the replacement has been successfully issued. This ensures TLS will not break for the hostname while the certificate is being replaced.

When the new certificate is successfully issued and activated, the status for the old certificate will transition from Pending Cleanup, and the certificate will be deleted.

Custom certificates

If you are using a custom certificate and your zone status is Pending or Moved, your certificate may have a status of Holding Deployment.

When your zone becomes active, your custom certificate will deploy automatically (also moving to an Active status).

If your zone is already active when you upload a custom certificate, you will not see this status.

Staging certificates

When you create certificates in your staging environment, those staging certificates have their own set of statuses:

Client certificates

When you use client certificates, those client certificates have their own set of statuses:


Monitor certificate statuses

SSL/TLS

Monitor a certificate's status on the Edge Certificates page or by using the Get Certificate Pack endpoint.

For more details on certificate validation, refer to Domain Control Validation.

SSL for SaaS

Monitor a certificate's status on the Custom Hostnames page or by using the Custom Hostname Details endpoint.

The Custom Hostname Details endpoint returns separate status fields for hostname activation and certificate status. Use the top-level status field to monitor hostname activation. Use the nested ssl.status field to monitor certificate issuance and deployment.

For production HTTPS, treat a custom hostname as ready when both status fields are active and the customer's DNS points to your Cloudflare for SaaS target.

For more details on certificate validation, refer to Issue and validate certificates.

Via the command line

To view certificates, use openssl or your browser. The command below can be used in advance of your customer pointing the app.example.com hostname to the edge (provided validation was completed).

openssl s_client -servername app.example.com -connect $CNAME_TARGET:443 </dev/null 2>/dev/null | openssl x509 -noout -text | grep app.example.com

Validity periods and renewal

import { Render } from "~/components";

For certificates managed by Cloudflare, attempts to renew start at the auto renewal period and continue up until 24 hours before expiration. The auto renewal period varies according to the certificate validity period, as explained in the sections below.

If a certificate fails to renew and another valid certificate exists for the hostname, Cloudflare will deploy the valid certificate within the last 24 hours before expiration.

Certificate types

Universal SSL

Advanced certificates

When you order an advanced certificate, you can select different certificate validity periods. Each certificate validity period has a corresponding auto renewal period, when attempts to renew will start.

Certificate validity period Auto renewal period Notes
1 year 30 days Limited to Enterprise customers using advanced certificates with SSL.com
3 months 30 days
1 month 7 days Not supported by Let's Encrypt
2 weeks 3 days Not supported by Let's Encrypt

:::note

For more details on the validity_days parameter used in API calls, refer to Order Advanced Certificate Pack.

:::

Custom certificates

For information regarding custom certificates (managed by you), consider this other page on renewal and expiration.

SSL for SaaS

For SSL for SaaS certificates, refer to Renew certificates.

Domain control validation (DCV)

HTTP validation is attempted on renewals and may fall back to TXT validation for certificate flows covered by this schedule:

This fallback schedule does not apply to Custom Hostname certificates. For more information, refer to Renew Custom Hostname certificates.

Benefits of shorter validity periods

Cloudflare only issues certificates with validity periods of three months or less for two reasons.

First, shorter-lived certificates limit the damage from key compromise and mistaken issuance. Any compromised key material will be valid for a shorter period of time.

Second, shorter certificates encourage automation. The more frequently you have to do a task, the more likely you will want to automate it. Automation also means that you are less likely to let a certificate expire in production or give a person access to key material.

For more details on the benefits of shorter validity periods, refer to our blog post introducing Advanced Certificate Manager.

Cloudflare and CVE-2019-1559

The GOLDENDOODLE and Zombie POODLE attacks affect applications that use certain cipher suites associated with TLS 1.2.

Any application on Cloudflare, however, is not vulnerable to these attacks because Cloudflare does not use the affected version of openssl at its edge.

Cloudflare could not remove these cipher suites from our edge by default because we did not want to break customer applications using legacy cipher suites.

Remove warnings from external security scanners

Even though your application is not vulnerable to CVE-2019-1559, some security scanners may flag your application erroneously.

To remove these warnings, refer to Customize cipher suites and exclude the following ciphers:

PCI DSS compliance

import { DashButton, APIRequest } from "~/components";

The Payment Card Industry Data Security Standard (PCI DSS) applies to any organization that stores, processes, or transmits payment card data. When your site or application runs behind Cloudflare, several PCI DSS requirements apply to how Cloudflare handles your traffic — and some require explicit configuration on your zone.

This guide walks through the Cloudflare configuration steps required for PCI DSS compliance, explains how Cloudflare interacts with PCI Approved Scanning Vendor (ASV) scans, and lists known scanner false positives.

Cloudflare's PCI DSS certification

Cloudflare is certified as a Level 1 PCI DSS Service Provider — the highest certification level. You can obtain Cloudflare's current Attestation of Compliance (AOC) from the Cloudflare Trust Hub.

:::note Cloudflare's AOC covers Cloudflare's own infrastructure. It does not automatically extend to your zone or application. You are responsible for configuring Cloudflare correctly and securing your own systems. :::

Shared responsibility

Area Cloudflare You
TLS protocol support Supports TLS 1.2 and 1.3 on all plans Set minimum TLS version to 1.2 on your zone
Cipher suites Offers PCI DSS-approved cipher suites Enable the PCI DSS cipher suite profile on your zone. Configuring cipher suites requires an Advanced Certificate Manager subscription.
Vulnerability patching Patches Cloudflare infrastructure (ROBOT, Sweet32, and others) Keep your origin server and any third-party software patched
Client-side scripts Client-Side Security Advanced inventories and monitors payment page scripts Enable and configure Client-Side Security

Configure TLS settings

Steps 1 and 2 are required for PCI DSS compliance. Step 3 is Cloudflare's recommendation for a stronger configuration but is not mandated by PCI DSS v4.0, which sets TLS 1.2 as the minimum. A PCI scan checks each layer independently — completing only Steps 1 and 2 is sufficient to meet the standard.

Step 1: Set minimum TLS version to 1.2

PCI DSS requirement 4.2.1 mandates strong cryptography for cardholder data in transit, with TLS 1.2 as the minimum acceptable version. TLS 1.0 and TLS 1.1 are not considered strong cryptography under PCI DSS.

  1. In the Cloudflare dashboard, go to SSL/TLS > Edge Certificates.

  2. For Minimum TLS Version, select TLS 1.2 or higher.

Refer to Minimum TLS Version for API and Terraform options.

Step 2: Configure PCI DSS cipher suites

PCI DSS prohibits weak and deprecated cipher algorithms. You must restrict your zone to the PCI DSS-approved cipher list.

:::note[Prerequisite] Cipher suite customization requires an Advanced Certificate Manager subscription. :::

:::note

Follow the steps in Customize cipher suites (dashboard) and select the cipher suites from the PCI DSS profile listed in Compliance standards. Alternatively, use the API:

<APIRequest path="/zones/{zone_id}/settings/{setting_id}" method="PATCH" json={{ value: [ "ECDHE-ECDSA-AES128-GCM-SHA256", "ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-ECDSA-AES256-GCM-SHA384", "ECDHE-RSA-AES256-GCM-SHA384", "ECDHE-ECDSA-CHACHA20-POLY1305", "ECDHE-RSA-CHACHA20-POLY1305", ], }} parameters={{ setting_id: "ciphers", }} />

Step 3: Enable TLS 1.3 (recommended)

TLS 1.3 provides stronger security guarantees than TLS 1.2, eliminates several legacy handshake patterns, and is recommended alongside TLS 1.2 for a stronger, future-proof configuration. It is not required for PCI DSS compliance, which mandates TLS 1.2 as the minimum.

  1. In the Cloudflare dashboard, go to SSL/TLS > Edge Certificates.

  2. Enable TLS 1.3.

Refer to TLS 1.3 for API and Terraform options.

Verify your configuration

After applying all settings, confirm that non-compliant connections are rejected.

Use an online TLS scanner

Online TLS scanners give you an external view of your configuration — the same perspective a PCI ASV scan sees. Two commonly used options are:

:::note Cloudflare does not endorse any specific third-party tool. Use any scanner that fits your workflow — what matters is verifying from outside the Cloudflare dashboard. :::

Use openssl

openssl s_client lets you test specific TLS versions from the command line. Connections using TLS 1.0 or TLS 1.1 should fail:

# Should fail — TLS 1.0 rejected
openssl s_client -connect example.com:443 -tls1

# Should fail — TLS 1.1 rejected
openssl s_client -connect example.com:443 -tls1_1

A rejected connection returns an error such as:

4087F5C1E27F0000:error:0A00042E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version

To confirm which cipher suite is negotiated over TLS 1.2:

openssl s_client -connect example.com:443 -tls1_2 2>/dev/null | grep -E "Protocol|Cipher"

The output should show a cipher from the PCI DSS-approved list — for example ECDHE-RSA-AES128-GCM-SHA256.

Use curl

To confirm TLS 1.0 and TLS 1.1 are rejected:

# Should fail — TLS 1.0 rejected
curl https://example.com --tls-max 1.0 -svo /dev/null

# Should fail — TLS 1.1 rejected
curl https://example.com --tls-max 1.1 -svo /dev/null

A rejected connection returns an error such as:

* error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert

Check from the dashboard

On the Edge Certificates page, select View current ciphers to see the cipher suites configured on your zone.

:::note The dashboard shows your configured cipher suites. The ciphers actually negotiated in a TLS handshake depend on the connecting client and certificate algorithm (RSA vs. ECDSA). Use SSL Labs or openssl s_client for the external view that a PCI scanner sees. :::

Cloudflare Pages

It is not possible to configure minimum TLS version or cipher suites for *.pages.dev hostnames. These settings only apply to zones you control in the Cloudflare dashboard.

For payment pages hosted on a Pages project, use a custom domain attached to a zone you control. Zone-level TLS and cipher suite settings apply to traffic served through that custom domain.

PCI DSS v4 client-side requirements

PCI DSS v4.0 introduced two requirements for scripts running in the consumer's browser on payment pages:

Requirement Description Cloudflare feature
6.4.3 Maintain an inventory of all scripts on payment pages, with authorization and integrity checks Page Shield
11.6.1 Detect and alert on unauthorized changes to HTTP security headers and payment page content Page Shield

Refer to Client-side security and PCI DSS compliance for setup guidance.

PCI ASV scans

PCI DSS requires quarterly vulnerability scans by an Approved Scanning Vendor (ASV). When your domain is proxied through Cloudflare, ASV scanners interact with Cloudflare's edge network rather than your origin server directly. Several behaviors commonly arise.

TCP source port behavior

Some ASV tools report a TCP Source Port Pass Firewall finding against Cloudflare-proxied IP addresses. This is a false positive caused by how Cloudflare's anycast network handles TCP connections — the behavior is a property of Cloudflare's infrastructure, not a vulnerability in your environment.

If your QSA or scanning tool flags this finding, provide:

Your QSA can treat this as a compensating control or documented exception based on Cloudflare's shared responsibility boundary.

WAF and DDoS blocking ASV scanners

ASV scanners send attack-pattern traffic — SQL injection probes, XSS payloads, vulnerability fingerprinting — to test your application. Cloudflare's WAF blocks many of these probes, which is correct WAF behavior, but it can prevent the scanner from completing its assessment.

To allow a scan without disabling your WAF:

  1. Obtain the source IP ranges used by your ASV vendor.
  2. Create a WAF custom rule that skips managed ruleset matching for those IP ranges, scoped to your scan maintenance window.
  3. Remove or disable the rule immediately after the scan completes.

:::caution Keep the WAF exception as narrow as possible — scoped to the scanner's IP range only. Remove it as soon as scanning is complete. :::

Non-standard ports

Cloudflare proxies a defined set of HTTP and HTTPS ports. For ports outside that list, Cloudflare's anycast network may cause those ports to appear open at the TCP layer even though they are not proxied — the TCP connection is accepted at the edge but HTTP/HTTPS requests are blocked at the application layer before reaching your origin.

If an ASV scan targets non-proxied ports, findings for those ports reflect Cloudflare's edge behavior rather than your origin. Configure your scan to target the ports your application actually serves on, and provide your QSA with the network ports reference to document the expected behavior.

Vulnerability mitigations

Cloudflare applies these mitigations by default across all proxied zones. No configuration is needed.

Cloudflare does not support:

Cloudflare mitigates:

All Cloudflare servers are patched against Heartbleed, Lucky Thirteen, and CCS injection vulnerability.

Common scanner false positives

ROBOT

Security scans that report Return of Bleichenbacher's Oracle Threat (ROBOT) against a Cloudflare-proxied domain are false positives. Cloudflare validates RSA PKCS#1 v1.5 padding in real time and substitutes a random session key if padding is incorrect, eliminating any exploitable oracle.

Sweet32 (CVE-2016-2183)

If a scanner flags Sweet32, verify that TLS 1.0 is disabled on your zone. Refer to Set minimum TLS version to 1.2 for steps. With TLS 1.0 disabled, the 3DES cipher suites where Sweet32 applies are not in use and the finding does not apply to your environment.

Cloudflare sets the _cfuvid cookie on some zones for rate limiting. Some scanners may report this cookie as missing the Secure attribute if they scan over HTTP. If your ASV raises this finding, confirm that your ASV is scanning HTTPS endpoints and that your zone redirects HTTP traffic to HTTPS. Refer to Always Use HTTPS for setup steps.

Reference

import { DirectoryListing } from "~/components"

For more on Cloudflare SSL/TLS, refer to these articles:

TLS protocols

Cloudflare supports the following TLS protocols:

TLS 1.0 is the version that Cloudflare sets by default for all customers using certificate-based encryption.

For information about which cipher suites are supported between clients and the Cloudflare network, refer to Cipher suites.

Understand TLS versions

A higher TLS version implies a stronger cryptographic standard. TLS 1.2 includes fixes for known vulnerabilities found in previous versions.

As of June 2018, TLS 1.2 is the version required by the Payment Card Industry (PCI) Security Standards Council. Cloudflare recommends migrating to TLS 1.2 to comply with the PCI requirement.

TLS 1.3, which offers additional security and performance improvements, was approved by the Internet Engineering Task Force (IETF) in May 2018.

:::note[PayPal's TLS 1.2 requirement]

Using Cloudflare does not affect PayPal's TLS 1.2 requirement. However, note that PayPal IPN (Instant Payment Notification) might not support TLS version 1.3. If you are encountering issues with PayPal IPN when the traffic is proxied by Cloudflare, try setting the Minimum TLS version to 1.2.

:::

Decide which version to use

TLS 1.3 has become widely adopted. As a general rule, Cloudflare recommends setting TLS to 1.3, as it will provide the best security.

However, not all browser versions support TLS 1.2 and above. Depending on your particular business situation, this may present some limitations in using stronger encryption standards:

DigiCert Legacy Root (G1) distrust by major browsers

Browsers and operating systems are completing the removal of DigiCert's legacy G1 root certificates from their trust stores, effective April 15, 2026.

DigiCert announced this planned deprecation in 2023 and has been issuing certificates from their newer G2 roots since 2020.

Since DigiCert is not within the certificate authorities used by Cloudflare, this change may only affect customers who upload custom certificates issued from DigiCert G1 roots.

The change

The primary root being distrusted is DigiCert Global Root CA. The distrust also affects other legacy G1 intermediates cross-signed from this root.

DigiCert Global Root G2 and G3 remain fully trusted. Certificates that chain to G2 are unaffected.

Refer to DigiCert's root and intermediate CA certificate updates for the full list of affected roots.

DigiCert's recommendation

DigiCert recommends reissuing any affected certificates from a G2 intermediate. This is a standard reissuance — you do not need to generate a new key in most cases.

Cloudflare-managed certificates

Since Cloudflare does not use DigiCert roots, you can avoid this dependency entirely by switching to Cloudflare-managed certificates:

More resources

Entrust distrust by major browsers

import { Details } from "~/components";

Google Chrome and Mozilla have announced they will no longer trust certificates issued from Entrust's root CAs.

Since Entrust is not within the certificate authorities used by Cloudflare, this change may only affect customers who upload custom certificates issued by Entrust.

The decision

New Entrust certificates issued on November 12, 2024 or after will not be trusted on Chrome by default. And new Entrust certificates issued on December 1, 2024 or after will not be trusted on Mozilla by default.

Refer to the announcements (Chrome, Mozilla) for a full list of roots that will be distrusted.

Entrust's response

To prevent their customers from facing issues, Entrust has partnered with SSL.com, a different certificate authority, trusted by both Chrome and Mozilla.

This means that Entrust certificates will be issued using SSL.com roots.

Cloudflare-managed certificates

Since Cloudflare also partners with SSL.com, you can switch from uploading custom certificates to using Cloudflare-managed certificates. This change brings the following advantages:

More resources

Migration guides

import { DirectoryListing } from "~/components"

These guides walk you through the migration processes associated with various changes in Cloudflare's SSL/TLS infrastructure.

ERR_SSL_PROTOCOL_ERROR

import { DashButton } from "~/components";

If visitors to your site experience SSL protocol errors such as:

These errors indicate that the SSL/TLS handshake failed. This can happen for many reasons, including certificate issues, protocol incompatibilities, or network interference.

Rule out common causes first

Before investigating protocol-specific issues, verify that the error is not caused by:


Test HTTP/3 (QUIC) compatibility

HTTP/3 uses the QUIC protocol over UDP, which some networks, firewalls, or devices do not fully support. If visitors experience intermittent SSL protocol errors, HTTP/3 may be the cause.

When to suspect HTTP/3 issues

How to test

Temporarily disable HTTP/3 to determine if it is the cause:

  1. In the Cloudflare dashboard, go to the Protocol Optimization page.
  2. Turn off HTTP/3 (with QUIC).
  3. Ask the affected visitor to test again.

If disabling HTTP/3 resolves the issue, the visitor's network likely blocks or mishandles UDP traffic on port 443. Re-enable HTTP/3 after testing and work with the visitor to identify the specific network issue.


Test TLS 1.3 compatibility

TLS 1.3 is the latest version of the TLS protocol and provides improved security and performance. However, some network security devices that perform SSL/TLS inspection may not fully support TLS 1.3.

When to suspect TLS 1.3 issues

How to test

:::caution Disabling TLS 1.3 reduces security for all visitors. Only disable it temporarily for diagnostic purposes. :::

Temporarily disable TLS 1.3 to determine if it is the cause:

  1. In the Cloudflare dashboard, go to the Edge Certificates page.
  2. Find TLS 1.3 and turn it off.
  3. Ask the affected visitor to test again.

If disabling TLS 1.3 resolves the issue, the visitor's network has a middlebox (firewall, proxy, or antivirus) that does not support TLS 1.3. Re-enable TLS 1.3 after testing and ask the visitor to:

If you cannot identify the root cause, contact Cloudflare Support with packet captures from the affected visitor showing the failed TLS handshake.


ISP and network interference

Some Internet Service Providers (ISPs) and corporate networks deploy security features that can interfere with HTTPS connections:

How to identify network interference

Ask the affected visitor to:

  1. Try a different network - Use mobile data instead of Wi-Fi, or try a different ISP
  2. Use a VPN - If the site works through a VPN, the ISP or local network is likely interfering
  3. Disable local security software - Temporarily disable antivirus or firewall software to test
  4. Check with their ISP - Some ISPs have security features that can be disabled upon request

If network interference is confirmed

If the issue is caused by the visitor's ISP or network:


Collect diagnostic information

If the above steps do not resolve the issue, collect the following information from affected visitors:

  1. Cloudflare diagnostic data - Ask the visitor to access https://your-domain.com/cdn-cgi/trace and share the output
  2. Exact error message - The full error text and error code from the browser
  3. Browser and OS version - Including any security software installed
  4. Network information - Whether they are on a corporate network, using a VPN, or have any proxy configured

Check Cloudflare Status to verify there are no ongoing incidents affecting SSL/TLS.

If the issue persists and affects many visitors, contact Cloudflare Support with the diagnostic information collected.

General SSL errors

import { GlossaryTooltip, DashButton } from "~/components";

Let's Encrypt chain update

Symptom

Starting September 9, 2024, visitors that try to connect to your website using older devices - for example, Android 7.0 and earlier - have access problems or reach security warnings.

Resolution

The fastest way to resolve this issue is to change your certificate to use Google Trust Services as the certificate authority.

Outdated browsers

Symptom

Until Cloudflare provides an SSL certificate for your domain, the following errors may appear in various browsers for HTTPS traffic:

Resolution

Even with a Cloudflare SSL certificate provisioned for your domain, older browsers display errors about untrusted SSL certificates because they do not support the Server Name Indication (SNI) protocol used by Cloudflare Universal SSL certificates.

To solve, determine if the browser supports SNI. If not, upgrade your browser.

:::note

It is possible for Cloudflare Support to enable non-SNI support for paid plans using any certificate.

:::


Only some of your subdomains return SSL errors

Symptom

Cloudflare Universal SSL certificates only cover the apex domain (example.com) and one level of subdomains (blog.example.com). If visitors to your domain observe errors accessing a second level of subdomains in their browser (such as dev.www.example.com) but not the first level of subdomains, resolve the issue using one of the following methods below.

Resolution


Your Cloudflare Universal SSL certificate is not active

Symptom

All active Cloudflare domains are provided a Universal SSL certificate. If you observe SSL errors and do not have a certificate of Type Universal within the Edge Certificates tab of the Cloudflare SSL/TLS app for your domain, the Universal SSL certificate has not yet provisioned.

Our SSL vendors verify each SSL certificate request before Cloudflare can issue a certificate for a domain name. This process may take anywhere from 15 minutes to 24 hours. Our SSL certificate vendors sometimes flag a domain name for additional review.

Resolution

No Universal certificate

If your Cloudflare SSL certificate is not issued within 24 hours of Cloudflare domain activation:

Temporarily pausing Cloudflare will allow the HTTPS traffic to be served properly from your origin web server while the support team investigates the issue.

Full DNS setup

If your domain is on a full setup, review your DNS records.

Cloudflare SSL/TLS certificates only apply for traffic proxied through Cloudflare. If SSL errors only occur for hostnames not proxied to Cloudflare, proxy those hostnames through Cloudflare.

Partial DNS setup

If your domain is on a CNAME setup (partial), confirm whether you have CAA DNS records enabled at your current hosting provider. If so, ensure you specify the Certificate Authorities that Cloudflare uses to provision certificates for your domain.


OCSP response error

Symptom

Visitors to your site observe an OCSP response error.

Resolution

This error is either caused by the browser version or an issue requiring attention by one of Cloudflare’s SSL vendors. In order to properly diagnose, contact Support with the following information provided by the visitor that observes the browser error:

  1. The output from https://aboutmybrowser.com/  .
  2. The output of https://<YOUR_DOMAIN>/cdn-cgi/trace from the visitor’s browser.

Incorrect HSTS headers

Symptom

The HSTS headers (Strict-Transport-Security and X-Content-Type-Options) in the response do not match the configuration settings defined in your HSTS settings.

Resolution

You may have configured Response Header Transform Rules that are overriding the HSTS header values defined in the SSL/TLS app.

  1. In the Cloudflare dashboard, go to the Rules Overview page.

  2. Under Response Header Transform Rules, search for a rule setting the value of one of the HSTS headers (Strict-Transport-Security or X-Content-Type-Options).

  3. Delete (or edit) the rule so that the HSTS configuration settings defined in the SSL/TLS app are applied.

  4. Repeat this procedure for the other HSTS header.


Other errors

Symptom

You are getting the error NET::ERR_CERT_COMMON_NAME_INVALID in your browser.

Resolution

:::note

The following openssl command might help troubleshooting TLS handshake between the client and the Cloudflare network edge:

openssl s_client -connect example.com:443 -servername example.com version

:::


Kaspersky Antivirus

To avoid SSL errors with the Cloudflare dashboard when using Kaspersky Antivirus, allow dash.cloudflare.com in Kaspersky.


Certificate Approval renewal email

Symptom

When clicking Approve Certificate on a Certificate Approval renewal email, you get the following error message:

An error occurred while attempting to validate your domain. Please try again later or contact support for assistance.

Resolution

Check the status of the certificate on the Cloudflare dashboard. If the status is Active, you can disregard this email and the error message.

Troubleshooting

import { ResourcesBySelector } from "~/components"

For FAQs and other troubleshooting information, refer to the following resources:

<ResourcesBySelector directory="ssl" types={["faq", "troubleshooting"]} filterables={["pcx_content_type"]} showDescriptions={false} />

Mixed content errors

Domains added to Cloudflare receive SSL certificates and can serve traffic over HTTPS. However, after starting to use Cloudflare, some customers notice missing content or page rendering issues when they first serve HTTPS traffic.

Typically, the problem is due to a request for HTTP resources from a web page served over HTTPS. For example, you type https://example.com in a browser and the page contains an image reference via HTTP in the HTML to <img src="http://example.com/resource.jpg">.

Normally, if your website loads all resources securely over HTTPS, visitors observe a lock icon in the address bar of their browser.

This indicates your site has a working SSL certificate and all resources loaded by the site are loaded over HTTPS. The green lock assures visitors that their connection is safe. One of the symptoms of mixed content is that different icons appear instead of the green lock icon.


Symptoms of mixed content occurrence

Most modern browsers block HTTP requests on secure HTTPS pages. Blocked content can include images, JavaScript, CSS, or other content that affects how the page looks or behaves.

Browser indications

Each web browser uses different methods to warn visitors about mixed content on a website, potentially including:

Console logs

For mixed content warnings, the web browser loads the resources but users do not see the lock icon in the URL. Warning messages appear within the browser’s debug tools:

Screenshot of mixed content warnings displayed in a browser console.

For mixed content errors, the browser refuses to load the resources over an insecure connection:

Screenshot of mixed content errors displayed in a browser console.

Information on using the browser’s debug tools to locate these issues are found in the documentation for Chrome and Firefox. Alternatively, you can view your page source and find specific references of http:// for paths to other resources.


Resolution

General advice

There are two methods to resolve mixed content errors.

  1. Load all resources via your HTML source without specifying the HTTP or HTTPS protocols. For example, using /domain.com/path/to.file instead of http://domain.com/path/to.file.
  2. Depending on your Content Management System, check for plugins that automatically rewrite HTTP resources to HTTPS. Cloudflare provides such a service via Automatic HTTPS Rewrites.

WordPress users

Cloudflare recommends WordPress users to install the Cloudflare WordPress plugin and enable the Automatic HTTPS rewrites option within the plugin.


ERR_TOO_MANY_REDIRECTS

After you add a new domain to Cloudflare, your visitors' browsers might display ERR_TOO_MANY_REDIRECTS or The page isn’t redirecting properly errors.

This error occurs when visitors get stuck in a redirect loop.

flowchart LR
accTitle: Redirect loops illustration
A[Request for <code>http://</code><code>example.com</code>] --> B[Redirect to <code>https://</code><code>example.com</code>]
B --> C[Redirect to <code>http://</code><code>example.com</code>]
C --> B
subgraph Redirect Loop
B
C
end

This error is commonly caused by:

:::note

For assistance determining if your origin web server is responding with redirects, contact your hosting provider or site administrator.

:::


Encryption mode misconfigurations

Your domain's SSL/TLS Encryption mode controls how Cloudflare connects to your origin server and how SSL certificates presented by your origin will be validated.

This setting can cause redirect loops when the value you set in Cloudflare conflicts with the settings at your origin web server.

Flexible encryption mode

If your domain's encryption mode is set to Flexible, Cloudflare sends unencrypted requests to your origin server over HTTP.

Redirect loops will occur if your origin server automatically redirects all HTTP requests to HTTPS.

flowchart TD
accTitle: Redirect loops illustration for Flexible mode
A[Request for <code>https://</code><code>example.com</code>] --> B[Encryption mode redirects to <code>http://</code><code>example.com</code>]
B --> C[Origin server redirects to <code>https://</code><code>example.com</code>]
C --> B
subgraph Cloudflare
B
end
subgraph Origin server
C
end

To solve this issue, either remove HTTPS redirects from your origin server or update your SSL/TLS Encryption Mode to be Full or higher (requires an SSL certificate configured at your origin server). To enforce HTTPS at the Cloudflare edge without setting up redirects at your origin, refer to Enforce HTTPS connections.

Full or Full (strict) encryption mode

If your domain's encryption mode is set to Full or Full (strict), Cloudflare sends encrypted requests to your origin server over HTTPS.

Redirect loops will occur if your origin server automatically redirects all HTTPS requests to HTTP.

flowchart TD
accTitle: Redirect loops illustration for Full or Full (strict) mode
A[Request for <code>http://</code><code>example.com</code>] --> B[Encryption mode redirects to <code>https://</code><code>example.com</code>]
B --> C[Origin server redirects to <code>http://</code><code>example.com</code>]
C --> B
subgraph Cloudflare
B
end
subgraph Origin server
C
end

To solve this issue, remove HTTP redirects from your origin server.


Edge certificate settings

Always use HTTPS

If you have Always Use HTTPS enabled for your domain, Cloudflare redirects all http requests to https for all subdomains and hosts in your application.

Redirect loops will occur if your origin server automatically redirects all HTTPS requests to HTTP.

flowchart TD
accTitle: Redirect loops illustration for Always Use HTTPS
A[Request for <code>http://</code><code>example.com</code>] --> B[Always Use HTTPS redirects to <code>https://</code><code>example.com</code>]
B --> C[Origin server redirects to <code>http://</code><code>example.com</code>]
C --> B
subgraph Cloudflare
B
end
subgraph Origin server
C
end

To solve this issue, remove HTTPS redirects from your origin server or disable Always Use HTTPS.

HSTS

If you have HTTP Strict Transport Security (HSTS) enabled for your domain, Cloudflare directs compliant web browsers to transform http links to https links.

Redirect loops will occur if your origin server automatically redirects all HTTPS requests to HTTP or if you have your domain's encryption mode set to Off.

flowchart TD
accTitle: Redirect loops illustration for HTTP Strict Transport Security
A[Request for <code>https://</code><code>example.com</code>] --> B[Encryption mode redirects to <code>http://</code><code>example.com</code>]
B --> C[HSTS redirects to <code>https://</code><code>example.com</code>]
C --> B
C --> D[Origin server redirects to <code>http://</code><code>example.com</code>]
D --> C
subgraph Cloudflare
B
C
end
subgraph Origin server
D
end

To solve this issue, remove HTTPS redirects from your origin server and make sure your domain's encryption mode is Flexible or higher.

Alternatively, disable HTTP Strict Transport Security (HSTS).


Redirect rules

Redirect loops can also occur if you have conflicting URL redirects.

flowchart TD
accTitle: Redirect loops illustration for redirect rules
A[Request for <code>https://</code><code>a.example.com</code>] --> B[Redirect to <code>http://</code><code>b.example.com</code>]
B --> C[Redirect to <code>https://</code><code>a.example.com</code>]
C --> B
subgraph Cloudflare
B
C
end

To solve this issue, review your various redirect rules and Page Rules to make sure no rules are not in conflict with each other.

:::note

To reduce the potential for redirect loops and mixed content errors, Cloudflare recommends WordPress users to install the Cloudflare WordPress plugin at their origin web server and enable the Automatic HTTPS rewrites option within the plugin.

:::

ERR_SSL_VERSION_OR_CIPHER_MISMATCH

import { Stream, Render } from "~/components";

After you add a new domain to Cloudflare, your visitors' browsers might display one of the following errors:

This error occurs when your domain or subdomain is not covered by an SSL/TLS certificate, which is usually caused by:

Decision tree

flowchart TD
accTitle: Troubleshooting ERR_SSL_VERSION_OR_CIPHER_MISMATCH decision tree
A>Is your certificate active?] -- Yes --> B>Is the DNS record proxied?]
A -- No --> C[Wait for certificate to activate or pause Cloudflare]
B -- No --> D[Proxy the DNS record]
B -- Yes --> E>Are you using a custom certificate?]
E -- Yes --> F[Custom certificate may be expired]
E -- No --> G>Are you accessing a multi-level subdomain?]
G -- Yes --> H[Get an advanced or custom certificate]

Certificate activation

Potential issues

If your visitors experience ERR_SSL_VERSION_OR_CIPHER_MISMATCH (Chrome) or SSL_ERROR_NO_CYPHER_OVERLAP (Firefox), check the status of your Universal certificate:

  1. Log into the Cloudflare dashboard.
  2. Choose your account and domain.
  3. Go to the Edge Certificates page.
  4. Find the certificate with the Type of Universal.
  5. Make sure the Status is Active.

If the Status is anything other than Active, you can either wait a bit longer for certificate activation or take immediate action.

Solutions

If you need to immediately resolve this error, temporarily pause Cloudflare.

Since Universal certificates can take up to 24 hours to be issued, wait and monitor the certificate's status. Once your certificate becomes Active, unpause Cloudflare using whichever method you used previously.

If your certificate is still not Active after 24 hours, try the various troubleshooting steps used to resolve timeout issues. If these methods are successful (and your certificate becomes Active), unpause Cloudflare using whichever method you used previously.


Proxied DNS records

Cloudflare Universal and Advanced certificates only cover the domains and subdomains you have proxied through Cloudflare.

If the Proxy status of A, AAAA, or CNAME records for a hostname are DNS-only, you will need to change it to Proxied.

Proxy status affects how Cloudflare treats traffic intended for specific DNS records


Certificate expiration

If you have a Custom certificate and visitors experience ERR_SSL_VERSION_OR_CIPHER_MISMATCH (Chrome) or SSL_ERROR_NO_CYPHER_OVERLAP (Firefox), check its status to make sure it is not expired.

If it is expired, upload a replacement certificate.


Multi-level subdomains

This means that you might experience ERR_SSL_VERSION_OR_CIPHER_MISMATCH (Chrome) or SSL_ERROR_NO_CYPHER_OVERLAP (Firefox) on multi-level subdomains.