Static certificates
The simplest approach is to provide certificate files directly:*.example.com) are supported. The first entry in the certificates array is used as the default when no SNI matches.
Arc reads certificate files at startup and re-reads them on hot reload (SIGHUP or file watcher change).
ACME — automatic certificate management
Arc can automatically obtain and renew certificates from Let’s Encrypt or any ACME-compatible CA.TLS-ALPN-01 challenge (recommended)
The certificate request and challenge are handled on the HTTPS listener itself. No HTTP port or DNS access needed:HTTP-01 challenge
Requires an HTTP listener on port 80:DNS-01 challenge
Supports Cloudflare, Route53, RFC2136, webhook, and external command: Cloudflare:Account key configuration
The ACME account key is stored encrypted on disk. Arc reads the passphrase from an environment variable or a file:TLS version and cipher control
mTLS to upstreams
Configure mutual TLS for upstream connections by adding atls block inside the upstream definition:
tls is present, Arc performs a TLS handshake with the upstream on every new connection. If client_cert_pem and client_key_pem are set, Arc presents a client certificate (mutual TLS).
SNI-based routing
Arc selects the appropriate certificate based on the TLS SNI extension in the ClientHello. The matching order:- Exact match (
example.com) - Wildcard match (
*.example.com) - Default (first certificate in the array)
Certificate renewal
Arc tracks certificate expiry and renews before therenew_before threshold (default: 30 days). On renewal:
- Arc contacts the ACME CA and completes the configured challenge
- The new certificate is stored and activated atomically via
ArcSwap - Existing TLS connections continue using the old certificate until they close
- New connections use the renewed certificate immediately
Troubleshooting
Certificate is not being served for a domain
Certificate is not being served for a domain
Check that the
sni field in certificates matches the hostname exactly, including wildcard syntax (*.example.com). The first certificate in the array is the default fallback when no SNI matches. Use openssl s_client -connect localhost:8443 -servername example.com to see which certificate Arc presents.ACME: challenge validation failed
ACME: challenge validation failed
TLS-ALPN-01 requires port 443 to be publicly reachable and the listener
name must match the listener field in acme.challenge. HTTP-01 requires port 80 and an http listener bound to that port. DNS-01 requires the DNS provider credentials to be correct and the domain’s authoritative nameservers to be reachable. ACME errors are written as system log entries. Check the access log for kind: "system" entries.Certificate not renewing automatically
Certificate not renewing automatically
Arc renews
renew_before ahead of expiry (default 720h). If the certificate is newer than renew_before, no renewal fires. Check arc_tls_cert_expiry_seconds in /metrics to see the time remaining. If renewal is overdue, check ACME challenge reachability.TLS handshake error: no certificates configured
TLS handshake error: no certificates configured
The listener kind is
https or h3 but no tls.certificates are present and tls.acme is not configured. Add at least one certificate entry or configure ACME.mTLS to upstream: certificate verify failed
mTLS to upstream: certificate verify failed
Ensure the upstream
tls.ca_pem points to the correct CA bundle. If the upstream uses a self-signed certificate, add tls.insecure: true (use only in development).
