Proxmox Let's Encrypt ACME Certificate Setup Guide
Set up free Let's Encrypt SSL certificates on Proxmox VE using the built-in ACME client. Works for homelab hosts using DNS challenge — no public IP needed.
On this page
The browser "Your connection is not private" warning on your Proxmox web UI is more than visual friction — every modern browser suppresses password autofill on untrusted origins, and if you're accessing your node through Tailscale or a reverse proxy, broken certificate validation creates real operational headaches. Proxmox VE 9.x ships a full ACME client built into both the web UI and CLI. In under 15 minutes, you can have a free, auto-renewing Let's Encrypt certificate on any Proxmox node — including homelab hosts with no public IP — using the DNS-01 challenge. This guide walks through the setup with Cloudflare as the DNS provider, but the same steps apply to AWS Route 53, Hetzner, DigitalOcean, and the 30+ other providers Proxmox ships plugins for.
Key Takeaways
- Built-in ACME client: No certbot or acme.sh needed — Proxmox VE has included its own ACME client since version 6.2.
- DNS-01 for homelabs: If your Proxmox host isn't publicly reachable on port 80, DNS-01 proves domain ownership through your DNS provider's API instead.
- Scoped API token: Create a Cloudflare token with
Zone:DNS:Editpermission only — do not use the global API key. - Auto-renewal: The
pve-daily-update.timersystemd unit renews certificates automatically when fewer than 30 days remain. - Per-node in clusters: Each cluster node needs its own ACME configuration — there is no cluster-wide certificate push.
Why the Default Self-Signed Certificate Is a Real Problem
Proxmox generates a self-signed certificate at install time using a local CA. Every browser flags it as untrusted, which means:
- Chrome and Firefox suppress password autofill on
https://pages with cert errors - Browser extensions and API clients refuse connections that fail certificate validation
- You train yourself to click through security warnings — exactly the reflex that Proxmox firewall and SSH hardening is designed to eliminate
A valid certificate fixes all of this and costs nothing beyond owning a domain.
Prerequisites
Before starting, confirm three things:
- You own a domain managed through a supported DNS provider (list available at
Datacenter > ACME > Challenge Plugins) - Your Proxmox node has outbound internet access to
acme-v02.api.letsencrypt.orgon port 443 - Your node's hostname is a fully qualified domain name
Check the current hostname:
hostname --fqdn
If the result is just pve with no domain suffix, fix it before proceeding. The Proxmox installation guide covers hostname configuration as part of its initial setup checklist, but the quick fix is:
hostnamectl set-hostname pve.yourdomain.com
Then update /etc/hosts so the node's IP maps to the FQDN:
192.168.1.10 pve.yourdomain.com pve
How to Register an ACME Account
Proxmox's ACME client needs a Let's Encrypt account to issue certificates. Register once per node.
Via the Web UI:
- Navigate to
Datacenter > ACME - Under "Accounts", click Add
- Enter your email address and accept the Terms of Service
- Select the Staging directory first — it has no rate limits and lets you validate the full flow without burning production quota
Via the CLI:
# Staging — use this first
pvenode acme account register staging your@email.com \
--directory https://acme-staging-v02.api.letsencrypt.org/directory
# Production — switch to this after staging succeeds
pvenode acme account register default your@email.com \
--directory https://acme-v02.api.letsencrypt.org/directory
List registered accounts at any point:
pvenode acme account list
HTTP-01 vs DNS-01: Which Challenge Type to Use
| Challenge | Requirement | Best for |
|---|---|---|
| HTTP-01 | Port 80 publicly reachable on your domain's IP | Public-facing hosts |
| DNS-01 | API access to your DNS provider | Homelabs, private IPs, wildcards |
| TLS-ALPN-01 | Port 443 publicly reachable | Rarely needed with Proxmox |
For a typical homelab Proxmox node, DNS-01 is the right call. Your host stays completely internal — only the Proxmox node needs outbound HTTPS access to Let's Encrypt's servers and your DNS provider's API. No inbound port forwarding required.
Setting Up the Cloudflare DNS Plugin
First, create a scoped API token in Cloudflare:
- Log into Cloudflare > My Profile > API Tokens > Create Token
- Select the Edit zone DNS template
- Scope it to your specific zone (domain) — not "All zones"
- Copy the token immediately — it won't be shown again
Add the plugin in Proxmox:
Web UI: Datacenter > ACME > Challenge Plugins > Add
- Plugin ID:
cloudflare - Plugin type:
Cloudflare Managed DNS - API Token: paste your token
CLI:
pvenode acme plugin add dns cloudflare \
--api cf \
--data "CF_Token=your_cloudflare_api_token_here"
Verify the plugin was saved:
pvenode acme plugin list
Configuring the Domain on Your Node
Attach a domain and the DNS plugin to your node's certificate configuration.
Web UI: Node > Certificates > ACME > Add
- Domain:
pve.yourdomain.com - Challenge type:
DNS - Plugin:
cloudflare
CLI:
# Set the ACME account for this node
pvenode config set --acme "account=default"
# Set the domain with the DNS plugin
pvenode config set --acmedomain0 "pve.yourdomain.com,plugin=cloudflare"
Verify the config was written correctly:
grep -E "^acme" /etc/pve/nodes/$(hostname)/config
Expected output:
acme: account=default
acmedomain0: pve.yourdomain.com,plugin=cloudflare
Ordering the Certificate
With the account and domain configured, request the certificate:
Web UI: Node > Certificates > ACME > Order Certificates Now
A task log shows the challenge flow in real time. DNS-01 validation against Cloudflare typically takes 30-60 seconds — Cloudflare's API propagation is fast enough that the challenge succeeds on the first validation attempt.
CLI:
pvenode acme cert order
If you're using the staging account, the certificate issuer will be "Fake LE Intermediate X1" — that's correct. Once staging succeeds, switch to the production account and re-order:
pvenode config set --acme "account=default"
pvenode acme cert order --force
After a successful order, the Proxmox web UI immediately starts serving the new certificate. Reload your browser — the padlock should now show a valid issuer.
How Auto-Renewal Works
Proxmox does not use a separate cron job for certificate renewal. The pve-daily-update.service systemd unit runs once per day and checks whether any node certificates expire within 30 days. If they do, it renews automatically via the same ACME config.
Check the timer status:
systemctl status pve-daily-update.timer
Trigger a manual renewal check:
pvenode acme cert renew
If a renewal fails silently, check the update log:
grep -i acme /var/log/pveupdate.log | tail -20
Expect to see lines confirming the renewal check ran and either skipped (cert still valid) or completed successfully.
Gotchas and Pitfalls From Real Use
Rate limits hit fast during testing: Let's Encrypt's production CA allows 5 failed certificate orders per domain per hour. If your plugin config is wrong and you retry quickly, you'll burn the limit. Always test with the staging CA first — it has no rate limits.
DNS propagation timing: The Cloudflare plugin inserts the TXT record and then waits before signaling ACME to validate. Cloudflare is typically 5-15 seconds. Slower DNS providers can take 2-5 minutes, and the Proxmox ACME client's built-in propagation wait may time out before slower providers finish. If validation fails consistently with a non-Cloudflare provider, look for a sleep or propagation_seconds setting in its plugin script under /usr/share/proxmox-acme/dnsapi/.
Wildcard certificates require DNS-01: Let's Encrypt issues wildcard certs only via DNS-01. To get *.yourdomain.com, set:
pvenode config set --acmedomain0 "*.yourdomain.com,plugin=cloudflare"
Note that *.yourdomain.com covers pve.yourdomain.com but not the apex yourdomain.com. Add a second domain entry (--acmedomain1) for the apex if you need it.
Cluster nodes each need separate certs: In a three-node cluster, configure ACME independently on pve1, pve2, and pve3. Each node's config lives at /etc/pve/nodes/<nodename>/config. There is no mechanism to push a certificate from the cluster view. Once you've invested the time setting up a full Proxmox private cloud, budget an extra 10 minutes per additional node for certificate setup.
Port 8006 vs port 80: HTTP-01 challenge needs port 80 forwarded to the Proxmox host — not port 8006. Forwarding 80 → 8006 via NAT will fail the challenge because the ACME token is served on port 80, not the web UI port.
Verifying the Certificate
After ordering, confirm the cert details:
Web UI: Node > Certificates — you'll see the Let's Encrypt cert listed alongside the original self-signed CA cert.
CLI:
openssl x509 \
-in /etc/pve/local/pveproxy-ssl.pem \
-text -noout \
| grep -E "(Subject:|Issuer:|Not After)"
Expected output:
Subject: CN=pve.yourdomain.com
Issuer: C=US, O=Let's Encrypt, CN=R10
Not After : Jul 23 12:00:00 2026 GMT
The certificate is valid for 90 days. Proxmox renews it when fewer than 30 days remain, so in steady state you should never see expiry-related downtime.
Using a Different DNS Provider
Proxmox ships ACME DNS plugins for 30+ providers. List all available APIs:
ls /usr/share/proxmox-acme/dnsapi/
The naming convention: dns_cf.sh → pass --api cf to pvenode acme plugin add dns. For AWS Route 53:
pvenode acme plugin add dns myroute53 \
--api route53 \
--data "AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE&AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
If your DNS provider isn't in the list, the acme-dns delegation approach works universally — you create a CNAME from _acme-challenge.yourdomain.com to a subdomain on a separate acme-dns server you control. More setup, but compatible with any registrar.
Conclusion
Setting up Let's Encrypt on Proxmox takes about 15 minutes and permanently eliminates the certificate warning on your management interface. Register a staging account, add your DNS plugin, configure the domain, confirm the staging cert orders cleanly, then switch to production — the systemd timer handles every renewal from that point forward. This pairs directly with the steps in the Proxmox firewall, fail2ban, and SSH hardening guide to give your management interface a properly secured baseline from day one.