Custom SSL Certificates -- Upload and Manage
In this tutorial, you'll learn about Custom SSL Certificates. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
Custom SSL certificates allow you to upload your own TLS certificates from any Certificate Authority to Cloudflare, giving you full control over certificate providers, key algorithms, and validation methods. This is essential when you need to use a specific CA, require Extended Validation (EV) certificates, or want to manage certificates through your existing PKI infrastructure.
Why Custom SSL Certificates Matter
While Universal SSL covers most use cases, production environments often require specific certificate properties. Your organization may mandate certificates from a particular CA for Compliance reasons. You might need ECDSA certificates for performance, or you may operate under a private PKI with internal CAs. Custom SSL certificate management in Cloudflare supports these scenarios without sacrificing the performance and security benefits of Cloudflare's edge network.
Real-World Use Case
A financial services company required EV certificates from a specific CA for regulatory Compliance across 200 customer-facing domains. Their existing PKI team managed certificate issuance through a commercial CA with 2-year validity periods. By uploading custom certificates to Cloudflare, they maintained their Compliance requirements while eliminating the need to install certificates on individual origin servers. Certificate deployment across all 200 domains completed in under 10 seconds.
Certificate Requirements and Preparation
flowchart TD
A[Obtain Certificate from CA] --> B[Export in PEM Format]
B --> C{Check Key Type}
C -->|RSA| D[2048-bit or 4096-bit]
C -->|ECDSA| E[P-256 or P-384]
D --> F[Combine Cert + Chain]
E --> F
F --> G[Upload to Cloudflare]
G --> H[Deploy to Edge Network]
style A fill:#4a90d9,color:#fff
style G fill:#27ae60,color:#fff
style H fill:#e67e22,color:#fff
PEM Format Requirements
Cloudflare accepts certificates in PEM (Privacy Enhanced Mail) format. The certificate file must contain:
- The leaf certificate (your domain's certificate)
- All intermediate certificates in the chain
- The certificate must not be password-protected
Key Types and Sizes
Cloudflare supports the following key types for custom certificates:
- RSA 2048-bit and 4096-bit
- ECDSA P-256 and P-384
- The private key must not be encrypted (no passphrase)
Certificate Bundle
The certificate bundle must include the full chain from your leaf certificate up to (but not including) the root CA. Cloudflare does not require the root certificate because it is already trusted by browsers.
Uploading a Custom Certificate via API
# Upload a custom SSL certificate
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/custom_certificates" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"certificate": "-----BEGIN CERTIFICATE-----\n...leaf cert...\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n...intermediate...\n-----END CERTIFICATE-----",
"private_key": "-----BEGIN RSA PRIVATE KEY-----\n...key...\n-----END RSA PRIVATE KEY-----",
"type": "sni_custom"
}' | python3 -m json.tool
# Expected output:
# {
# "result": {
# "id": "custom-cert-id",
# "hosts": ["example.com"],
# "status": "active"
# },
# "success": true
# }
The API accepts the PEM certificate and private key as strings. The type parameter should be sni_custom for SNI-based custom certificates. Cloudflare validates the certificate chain, key match, and hostname coverage before deploying.
Listing and Managing Custom Certificates
# List all custom certificates in a zone
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/custom_certificates" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" | python3 -c "
import sys, json
data = json.load(sys.stdin)
for cert in data['result']:
print(f'ID: {cert[\"id\"]}, Status: {cert[\"status\"]}, Hosts: {cert[\"hosts\"]}, Expires: {cert.get(\"expires_on\", \"N/A\")}')
"
# Expected output:
# ID: abc123, Status: active, Hosts: ['example.com'], Expires: 2026-06-01
This command lists all custom certificates with their deployment status, covered hostnames, and expiry dates. Certificates with status active are deployed and serving traffic. pending_deployment means Cloudflare is still propagating the certificate across its edge network.
Replacing an Expiring Certificate
# Delete an old custom certificate and upload a replacement
OLD_CERT_ID="your-old-cert-id"
# Delete old certificate
curl -s -X DELETE "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/custom_certificates/$OLD_CERT_ID" \
-H "Authorization: Bearer YOUR_API_TOKEN" | python3 -m json.tool
# Upload new certificate (same format as above)
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/YOUR_ZONE_ID/custom_certificates" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"certificate": "-----BEGIN CERTIFICATE-----\n...new cert...\n-----END CERTIFICATE-----",
"private_key": "-----BEGIN EC PRIVATE KEY-----\n...new key...\n-----END EC PRIVATE KEY-----",
"type": "sni_custom"
}' | python3 -m json.tool
The delete-then-upload pattern ensures zero downtime during certificate rotation. Upload the new certificate first if your plan allows multiple custom certificates, then delete the old one. Cloudflare serves the most recently uploaded certificate for each hostname.
Common Errors and Troubleshooting
Certificate and Key Mismatch
Cloudflare validates that the private key matches the certificate. If they do not match, the upload fails with a key mismatch error. Solution: verify the key matches the certificate using openssl x509 -noout -modulus -in cert.pem | openssl md5 and openssl rsa -noout -modulus -in key.pem | openssl md5. The checksums must match.
Invalid PEM Format
The PEM file must have correct headers (-----BEGIN CERTIFICATE-----) and footers (-----END CERTIFICATE-----), proper line breaks (encoded as \n in JSON), and no extra whitespace. Solution: use openssl x509 -in cert.crt -outform PEM -out cert.pem to normalize formatting.
Certificate Chain Incomplete
If intermediate certificates are missing from the upload, some browsers and clients may reject the certificate. Solution: include all intermediate certificates in the bundle, ordered leaf first, then intermediates in chain order.
Private Key Encryption
Cloudflare does not accept password-protected private keys. Solution: remove the passphrase with openssl rsa -in encrypted.key -out decrypted.key.
Hostname Coverage Mismatch
The certificate must cover the hostnames it is uploaded for. A certificate for example.com cannot serve www.example.com unless the Subject Alternative Name (SAN) includes it. Solution: ensure the certificate SAN includes all hostnames you intend to cover.
Practice Questions
- What PEM format requirements must a custom SSL certificate meet before uploading to Cloudflare?
- How do you verify that a private key matches its corresponding certificate using OpenSSL?
- What happens if you upload a certificate whose hostnames do not match the zone's DNS records?
FAQ
Summary
Custom SSL certificates give you full control over certificate management within Cloudflare. You can upload certificates from any CA, use RSA or ECDSA keys, and manage the full certificate lifecycle through the API or dashboard. Proper PEM formatting, complete certificate chains, and matching private keys are essential for successful uploads. Custom certificates deploy globally within seconds, making them suitable for enterprise environments with specific Compliance or PKI requirements.
This guide is brought to you by the developers of Cloudflare, SSL, and Cyber Security products at DodaTech.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro