Error 429: too many certificates (5) already issued

So my little home API (served from my Raspberry Pi 3B) was working fine in a Docker container with DuckDNS + Let's Encrypt SSL until I did an upgrade to Docker Compose V2. Now when I run the V2 container I get this message:

Unable to obtain ACME certificate for domains "mysubdomain.duckdns.org": unable to generate a certificate for the domains [mysubdomain.duckdns.org]: acme: error: 429 :: POST :: https://acme-v02.api.letsencrypt.org/acme/new-order :: urn:ietf:params:acme:error:rateLimited :: Error creating new order :: too many certificates (5) already issued for this exact set of domains in the last 168 hours

Why did I get this error? I thought since I already have a valid working SSL cert Traefik would reuse it -- or does Traefik try to request a new cert every time I restart the container?

Another question: I also have a valid cert that was generated from Certbot that passed the DNS-01 challenge. Can I force Traefik to use this cert instead (the files inside /etc/letsencrypt/live/mysubdomain.duckdns.org)?

UPDATE

After some more reading with help from reddit, I think I'm closer to a solution (to reuse the SSL cert instead of requesting a new one after every container restart). Here's my current config...

docker-compose.yml

version: "3.8"

services:
  web:
    ...
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.pi.rule=Host(`mysubdomain.duckdns.org`)"
      - "traefik.http.routers.pi.tls=true"
      - "traefik.http.routers.pi.tls.certresolver=myresolver"

  traefik:
    environment:
      - DUCKDNS_TOKEN=<my_duckdns_token>
    image: traefik:v2.10.4
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./src/traefik.yml:/etc/traefik/traefik.yml"
      - "./letsencrypt:/letsencrypt"

traefik.yml

entryPoints:
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: :443

providers:
  docker:
    exposedByDefault: false

certificatesResolvers:
  myresolver:
    acme:
      email: myduckdns@email.com
      caserver: https://acme-staging-v02.api.letsencrypt.org/directory
      #storage: /letsencrypt/acme.json
      storage: /letsencrypt/acme.staging.json
      dnsChallenge:
        provider: duckdns

log:
  level: DEBUG

I'm following the advice of the docs to use a staging server to get the cert first before requesting a real cert. After starting up the container, I do see the letsencrypt/acme.staging.json file in the build context directory, and it contains "status": "valid" -- does this mean everything's OK with getting the staging cert?

However, I'm seeing this in the log:

traefik  | time="2023-09-01T09:31:22Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] acme: use dns-01 solver"
traefik  | time="2023-09-01T09:31:22Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] acme: Preparing to solve DNS-01"
traefik  | time="2023-09-01T09:31:23Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] acme: Trying to solve DNS-01"
traefik  | time="2023-09-01T09:31:23Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] acme: Checking DNS record propagation using [127.0.0.11:53]"
traefik  | time="2023-09-01T09:31:25Z" level=debug msg="legolog: [INFO] Wait for propagation [timeout: 1m0s, interval: 2s]"
traefik  | time="2023-09-01T09:31:28Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] The server validated our request"
traefik  | time="2023-09-01T09:31:28Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] acme: Cleaning DNS-01 challenge"
traefik  | time="2023-09-01T09:31:28Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] acme: Validations succeeded; requesting certificates"
traefik  | time="2023-09-01T09:32:03Z" level=debug msg="legolog: [INFO] Wait for certificate [timeout: 30s, interval: 500ms]"
traefik  | time="2023-09-01T09:32:04Z" level=debug msg="legolog: [INFO] [mysubdomain.duckdns.org] Server responded with a certificate."
traefik  | time="2023-09-01T09:32:04Z" level=debug msg="Certificates obtained for domains [mysubdomain.duckdns.org]" providerName=myresolver.acme ACME CA="https://acme-staging-v02.api.letsencrypt.org/directory" routerName=pi@docker rule="Host(`mysubdomain.duckdns.org`)"
traefik  | time="2023-09-01T09:32:04Z" level=debug msg="Configuration received: {\"http\":{},\"tcp\":{},\"udp\":{},\"tls\":{}}" providerName=myresolver.acme
traefik  | time="2023-09-01T09:32:04Z" level=debug msg="No entryPoint defined for this router, using the default one(s) instead: [web websecure]" routerName=pi
traefik  | time="2023-09-01T09:32:04Z" level=debug msg="Adding certificate for domain(s) mysubdomain.duckdns.org"
traefik  | time="2023-09-01T09:32:06Z" level=debug msg="No default certificate, fallback to the internal generated certificate" tlsStoreName=default

Is it normal to get "No default certificate" warning when using the Let's Encrypt staging server?

I just quickly scanned your post.

You need to persist the LE certs, either on host or in a Docker volume, otherwise you hit the limits. There is a big note in the docs about it.

Traefik uses a default certificate in case there is no existing one. You can declare a LE cert as default.

1 Like

Thanks, I will look into how to set a LE cert as default.