# Cloudflare Origin CA certificate setup with Full (strict)

> Create a free Cloudflare Origin CA certificate, install it on Nginx, switch SSL mode to Full (strict) and optionally use Authenticated Origin Pulls.

Source: https://ssl.sh/guides/cloudflare-origin-certificate/
Last updated: 2026-11-10

A Cloudflare Origin CA certificate encrypts the connection from Cloudflare to your origin. Create it in the dashboard, install it on the server and set the SSL mode to **Full (strict)** so Cloudflare validates it. Visitors still see Cloudflare's edge certificate.

The steps apply to any Cloudflare plan as of November 2026 and use an Nginx origin; the same files work on Apache or other servers.

## Prerequisites

The domain must already use Cloudflare's proxy.

- A domain active on Cloudflare, with the `A`/`AAAA` records for `example.com` and `www.example.com` proxied (orange cloud) and pointing at your origin, for example `203.0.113.10`.
- Nginx on the origin with port 443 reachable from Cloudflare.
- Access to the Cloudflare dashboard for the zone.

## Step 1: Create the Origin CA certificate

In the Cloudflare dashboard go to **SSL/TLS → Origin Server → Create Certificate**. Choose **Generate private key and CSR with Cloudflare**, key type ECC or RSA, hostnames `example.com` and `*.example.com`, and the validity you want (up to 15 years). Click **Create**, select PEM format, and copy both the **Origin Certificate** and the **Private Key**. The key is shown only once.

## Step 2: Install it on the origin

Save the certificate and key as two PEM files and point the 443 server block at them:

```bash
sudo mkdir -p /etc/ssl/cloudflare
sudo nano /etc/ssl/cloudflare/example.com.pem    # paste the Origin Certificate
sudo nano /etc/ssl/cloudflare/example.com.key    # paste the Private Key
sudo chmod 600 /etc/ssl/cloudflare/example.com.key
```

```nginx
server {
    listen 443 ssl;
    http2 on;    # nginx 1.25.1+
    server_name example.com www.example.com;

    ssl_certificate     /etc/ssl/cloudflare/example.com.pem;
    ssl_certificate_key /etc/ssl/cloudflare/example.com.key;
    ssl_protocols       TLSv1.2 TLSv1.3;

    root /var/www/example.com;
}
```

```bash
sudo nginx -t && sudo systemctl reload nginx
```

## Step 3: Switch to Full (strict)

In **SSL/TLS → Overview**, set the encryption mode to **Full (strict)**. Cloudflare now validates the origin certificate on every connection. Avoid **Flexible**, which sends traffic to the origin unencrypted and often causes redirect loops.

## Step 4: Redirect HTTP and restrict the origin

Enable **SSL/TLS → Edge Certificates → Always Use HTTPS** so visitors are redirected at the edge, and remove any port-80 redirect on the origin that could loop. Optionally enable **Authenticated Origin Pulls** so the origin accepts TLS connections only from Cloudflare; follow Cloudflare's documentation to download its client CA and add `ssl_client_certificate` and `ssl_verify_client on;` to Nginx. Restricting the origin firewall to Cloudflare's IP ranges is a further option.

## Verify

The public check shows Cloudflare's edge certificate, which is what visitors see. Use the [SSL checker](https://ssl.sh/tools/ssl-checker/), or from any terminal:

```bash
curl ssl.sh/example.com
```

To check the origin certificate itself, connect to the origin IP directly:

```bash
openssl s_client -connect 203.0.113.10:443 -servername example.com </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates
```

The issuer is Cloudflare's origin CA, and a browser connecting directly would not trust it, which is expected.

## Automatic renewal

Cloudflare renews the edge certificate (Universal SSL) automatically, but the Origin CA certificate does not renew itself. It is valid until the date you chose, after which Cloudflare returns 526 errors in Full (strict) mode. Put the expiry date in your monitoring and replace the certificate (Steps 1 and 2) well before it; Cloudflare also offers an API to create Origin CA certificates if you want to script it. Add the hostname to [ssl.sh monitoring](https://ssl.sh/monitor/) (in development) for the edge side.

## Troubleshooting

- **Error 526 Invalid SSL certificate**: the origin certificate is expired, missing the hostname, or Nginx serves a different certificate; check with the `openssl s_client` command above.
- **Error 525 SSL handshake failed**: Nginx is not listening with TLS on 443 or has no protocol in common with Cloudflare.
- **Visitors see an untrusted certificate**: the DNS record is not proxied (grey cloud), so browsers reach the origin directly; see [NET::ERR_CERT_AUTHORITY_INVALID](https://ssl.sh/errors/net-err-cert-authority-invalid/).
- **ERR_TOO_MANY_REDIRECTS**: the SSL mode is Flexible while the origin redirects to HTTPS; switch to Full (strict).
- **Mixed content after enabling HTTPS**: see [mixed content warning](https://ssl.sh/errors/mixed-content-warning/).
