Skip to content
ssldays

Guide

Where Traefik stores SSL certificates and renewal

Trace Traefik ACME storage, Kubernetes TLS secrets, and file provider paths so renewed certificates load on the entrypoint that serves your public hostname.

Updated May 30, 2026 814 words

Mapping the traefik ssl certificate path story—acme storage files, mounted PEM directories, and Kubernetes secrets—stops renewals that never reach the router customers actually hit.

Teams run Traefik with static YAML, Helm values, and cluster CRDs simultaneously. Certificate material may live in acme.json on a volume, in tls.crt keys inside namespaced Secrets, or in host paths referenced by the file provider. Renewal without knowing which store backs each router wastes cycles.

This guide helps operators inventory those paths, align cert-manager or ACME outputs with Traefik bindings, and verify presentation after rollout. ACME resolver misconfiguration is covered in depth in Traefik ACME certificate expired.

When PEMs update but serials stay stale on the internet, continue with Reload traefik after SSL certificate renewal.

What to check

List certificateResolvers in static configuration and note storage filenames and entryPoints for challenges. For Kubernetes, list Secrets referenced by Ingress, IngressRoute, or Gateway API resources and whether cert-manager owns them.

Document host bind mounts in Compose or Nomad jobs that map local directories into Traefik for file-provided certs. Confirm read-only mistaken mounts after security scans.

For each public hostname, write the chain: DNS name, router rule, tls section, secret or resolver name, physical storage path or Secret namespace.

Compare openssl serial against the newest object version in etcd or against acme storage timestamps after renewal.

Step-by-step

Static ACME storage

grep -R certificateResolvers /etc/traefik/ 2>/dev/null
ls -la /letsencrypt/acme.json /data/acme.json 2>/dev/null

Back up acme.json before edits. Ensure permissions allow the Traefik user to read and write.

Kubernetes TLS secrets

kubectl get secret -A -o custom-columns=NS:.metadata.namespace,NAME:.metadata.name,TYPE:.type \
  | grep kubernetes.io/tls
kubectl describe ingressroute -n prod your-route

When cert-manager renews, watch Certificate Ready status and confirm the Secret data keys tls.crt and tls.key updated.

File provider PEM directories

ls -la /certs/public/
openssl x509 -in /certs/public/app.example.com.crt -noout -dates -serial

Replace files atomically, then signal Traefik to reload configuration without dropping unrelated routes when your platform supports graceful updates.

Verify live presentation

HOST=app.example.com
echo | openssl s_client -connect "${HOST}:443" -servername "${HOST}" 2>/dev/null \
  | openssl x509 -noout -dates -serial

How to read the output

acme.json is a single JSON document holding ACME accounts and issued certificates for resolvers defined in static config. Corruption or loss presents as sudden expiry across all resolver-backed routers.

Kubernetes Secret resourceVersion changes after cert-manager renewal. Traefik may cache TLS until routers reload; if version changed but openssl did not, rollout or dynamic reload is missing.

File provider certificates show notAfter via openssl x509 on disk. Live serial should match after Traefik picks up filesystem changes.

Router describe output links hostnames to secret namespaces. Typos between namespaces duplicate secrets and leave production on an old copy.

Common mistakes

Renewing at cert-manager while Ingress still references a manually copied Secret in another namespace. Storing acme.json on emptyDir volumes.

Pointing routers at tls default certificate while expecting per-host ACME certificates. Updating PEM paths in Git but not rolling the DaemonSet that mounts them.

Assuming Helm chart defaults for storage paths match a previous manually installed Traefik instance.

Mixing static and dynamic provider definitions that both declare conflicting resolver names.

Multi-cluster GitOps repos should name Secret sources explicitly in architecture diagrams. On-call engineers should not hunt ten repositories to learn which traefik ssl certificate path backs checkout during a revenue event.

Object storage backups of acme.json need encryption and restore drills the same as database backups. Restoring an old acme file during DR can resurrect expired certificates across every resolver-backed router simultaneously.

Windows nodes running Traefik in Docker Desktop for local reproduction should not become the canonical documentation for Linux production paths. Maintain environment-specific path tables linked from the service catalog entry.

Contractors with kubectl access sometimes create duplicate tls secrets to test features, leaving production IngressRoute references stale. RBAC reviews and naming conventions reduce shadow secrets.

Regulated industries may require hardware security modules for private keys while still using Traefik for public termination. Document when paths reference HSM proxies instead of PEM files on disk so renewals route through the correct approval workflow.

Capacity planning for short-lived certificates should include time for rolling Traefik after each mass renewal. Path updates without coordinated rollouts extend incidents when only half the anycast pool serves fresh serials.

Training sessions for new hires should include finding acme.json on a read-only mount using kubectl describe volume mounts. Hands-on muscle memory beats wiki tables during overnight pages.

Vendor penetration reports listing expired paths should map back to the owning router in the same business day. Security and platform teams close the loop faster when tickets cite both the storage URI and the public hostname affected.

Treat path documentation as living configuration: when a chart bumps default mount paths during upgrades, update the runbook in the same merge request so traefik ssl certificate path references never lag production by one release train.

When to use automation

Path spreadsheets cannot keep pace with GitOps Secret churn and multi-cluster ingress. Monitor live TLS on each hostname Traefik advertises publicly.

SSLdays validates what the world receives on port 443, independent of whether material came from acme.json or a Kubernetes Secret. Threshold alerts at 30, 14, 7, and 1 days align with short-lived ACME lifetimes. Add RDAP domain expiration when hostname validation depends on registrar state.

Use /check after every storage migration, then promote hostnames into /register for scheduled polling. Webhooks on paid plans integrate with Slack and Discord for hourly monitoring at scale.

Frequently asked questions

Does cert-manager replace Traefik ACME?

Teams use both: cert-manager writes Secrets Traefik routers reference. Pick one issuer per hostname to avoid conflicting renewal schedules.

How do I find the Secret for a hostname?

Inspect Ingress or IngressRoute TLS sections and follow secretName. Tools like kubectl get ingress -o yaml speed this up during incidents.

Are file paths hot-reloaded?

Traefik watches some providers; Kubernetes updates often need controller awareness of Secret rotation. Verify with openssl after each change.

What permissions does acme.json need?

Traefik user read-write, no world permissions. SELinux or AppArmor denials after renewals mimic expiry until contexts are fixed.

Monitor this hostname on a schedule

Live certificate checks and renewal reminders — not guesswork from PEM files.