Wildcard certificate renewal fails with “no such file or directory” for key file

1. The problem I’m having:

I’m running Caddy in Docker and recently started seeing renewal failures for my wildcard certificate *.xd003.cc

2. Error messages and/or full log output:

caddy  | {"level":"info","ts":1762622403.7777982,"msg":"maxprocs: Leaving GOMAXPROCS=4: CPU quota undefined"}
caddy  | {"level":"info","ts":1762622403.7780037,"msg":"GOMEMLIMIT is updated","package":"github.com/KimMachineGun/automemlimit/memlimit","GOMEMLIMIT":22628214374,"previous":9223372036854775807}
caddy  | {"level":"info","ts":1762622403.7780392,"msg":"using config from file","file":"/etc/caddy/Caddyfile"}
caddy  | {"level":"info","ts":1762622403.7795942,"msg":"adapted config to JSON","adapter":"caddyfile"}
caddy  | {"level":"warn","ts":1762622403.7796478,"msg":"Caddyfile input is not formatted; run 'caddy fmt --overwrite' to fix inconsistencies","adapter":"caddyfile","file":"/etc/caddy/Caddyfile","line":2}
caddy  | {"level":"info","ts":1762622403.7834022,"logger":"admin","msg":"admin endpoint started","address":"localhost:2019","enforce_origin":false,"origins":["//[::1]:2019","//127.0.0.1:2019","//localhost:2019"]}
caddy  | {"level":"info","ts":1762622403.7836425,"logger":"tls.cache.maintenance","msg":"started background certificate maintenance","cache":"0x40006b6b00"}
caddy  | {"level":"info","ts":1762622403.7837856,"logger":"http.auto_https","msg":"server is listening only on the HTTPS port but has no TLS connection policies; adding one to enable TLS","server_name":"srv0","https_port":443}
caddy  | {"level":"info","ts":1762622403.7838013,"logger":"http.auto_https","msg":"enabling automatic HTTP->HTTPS redirects","server_name":"srv0"}
caddy  | {"level":"info","ts":1762622403.7839005,"logger":"http","msg":"enabling HTTP/3 listener","addr":":443"}
caddy  | {"level":"info","ts":1762622403.7846048,"logger":"http.log","msg":"server running","name":"srv0","protocols":["h1","h2","h3"]}
caddy  | {"level":"warn","ts":1762622403.784711,"logger":"http","msg":"HTTP/2 skipped because it requires TLS","network":"tcp","addr":":80"}
caddy  | {"level":"warn","ts":1762622403.7847235,"logger":"http","msg":"HTTP/3 skipped because it requires TLS","network":"tcp","addr":":80"}
caddy  | {"level":"info","ts":1762622403.7847266,"logger":"http.log","msg":"server running","name":"remaining_auto_https_redirects","protocols":["h1","h2","h3"]}
caddy  | {"level":"info","ts":1762622403.7847297,"logger":"http","msg":"enabling automatic TLS certificate management","domains":["*.xd003.cc"]}
caddy  | {"level":"info","ts":1762622403.7883356,"msg":"autosaved config (load with --resume flag)","file":"/config/caddy/autosave.json"}
caddy  | {"level":"info","ts":1762622403.788356,"msg":"serving initial configuration"}
caddy  | {"level":"info","ts":1762622403.791368,"logger":"tls","msg":"cleaning storage unit","storage":"FileStorage:/data/caddy"}
caddy  | {"level":"info","ts":1762622403.7926788,"logger":"tls","msg":"certificate expired beyond grace period; cleaning up","storage":"FileStorage:/data/caddy","asset_key":"certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.crt","expired_for":7173385.792677717,"grace_period":1209600}
caddy  | {"level":"info","ts":1762622403.7927027,"logger":"tls","msg":"deleting asset because resource expired","storage":"FileStorage:/data/caddy","asset_key":"certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.crt"}
caddy  | {"level":"info","ts":1762622403.7927544,"logger":"tls","msg":"deleting asset because resource expired","storage":"FileStorage:/data/caddy","asset_key":"certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.key"}
caddy  | {"level":"info","ts":1762622403.7927716,"logger":"tls","msg":"deleting asset because resource expired","storage":"FileStorage:/data/caddy","asset_key":"certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.json"}
caddy  | {"level":"info","ts":1762622403.7934582,"logger":"tls","msg":"deleting site folder because key is empty","storage":"FileStorage:/data/caddy","site_key":"certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc"}
caddy  | {"level":"info","ts":1762622403.7963326,"logger":"tls","msg":"finished cleaning storage units"}
caddy  | {"level":"info","ts":1762622404.8368266,"msg":"got renewal info","names":["*.xd003.cc"],"window_start":1752780462,"window_end":1752935911,"selected_time":1752927937,"recheck_after":1762644004.8367982,"explanation_url":""}
caddy  | {"level":"error","ts":1762622404.8370183,"logger":"tls","msg":"updating ARI upon managing","error":"got new ARI from acme-v02.api.letsencrypt.org-directory, but failed loading stored certificate metadata: loading cert metadata: open /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.json: no such file or directory"}
caddy  | {"level":"info","ts":1762622404.8370435,"logger":"tls","msg":"certificate needs renewal based on ARI window","subjects":["*.xd003.cc"],"expiration":1755449018,"ari_cert_id":"nytfzzwhT50Et-0rLMTGcIvS1w0.BWow56lX8w9SayBINRC9oP8M","next_ari_update":1762644004.8367982,"renew_check_interval":600,"window_start":1752780462,"window_end":1752935911,"selected_time":1752907091,"renewal_cutoff":1752906491}
caddy  | {"level":"info","ts":1762622404.8392873,"logger":"tls.renew","msg":"acquiring lock","identifier":"*.xd003.cc"}
caddy  | {"level":"info","ts":1762622404.8411217,"logger":"tls.renew","msg":"lock acquired","identifier":"*.xd003.cc"}
caddy  | {"level":"error","ts":1762622404.8411875,"logger":"tls.renew","msg":"will retry","error":"open /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.key: no such file or directory","attempt":1,"retrying_in":60,"elapsed":0.000049561,"max_duration":2592000}
caddy  | {"level":"error","ts":1762622464.844739,"logger":"tls.renew","msg":"will retry","error":"open /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.key: no such file or directory","attempt":2,"retrying_in":120,"elapsed":60.003599077,"max_duration":2592000}
caddy  | {"level":"error","ts":1762622584.8496995,"logger":"tls.renew","msg":"will retry","error":"open /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.key: no such file or directory","attempt":3,"retrying_in":120,"elapsed":180.008560444,"max_duration":2592000}
caddy  | {"level":"info","ts":1762622692.0590563,"logger":"admin.api","msg":"received request","method":"POST","host":"localhost:2019","uri":"/load","remote_ip":"127.0.0.1","remote_port":"51902","headers":{"Accept-Encoding":["gzip"],"Content-Length":["389"],"Content-Type":["application/json"],"Origin":["http://localhost:2019"],"User-Agent":["Go-http-client/1.1"]}}
caddy  | {"level":"info","ts":1762622692.0591526,"msg":"config is unchanged"}
caddy  | {"level":"info","ts":1762622692.059162,"logger":"admin.api","msg":"load complete"}
caddy  | {"level":"error","ts":1762622704.849988,"logger":"tls.renew","msg":"will retry","error":"open /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.key: no such file or directory","attempt":4,"retrying_in":300,"elapsed":300.008846575,"max_duration":2592000}
caddy  | {"level":"info","ts":1762623003.7838001,"logger":"tls","msg":"certificate needs renewal based on ARI window","subjects":["*.xd003.cc"],"expiration":1755449018,"ari_cert_id":"nytfzzwhT50Et-0rLMTGcIvS1w0.BWow56lX8w9SayBINRC9oP8M","next_ari_update":1762644004.8367982,"renew_check_interval":600,"window_start":1752780462,"window_end":1752935911,"selected_time":1752907091,"renewal_cutoff":1752906491}
caddy  | {"level":"warn","ts":1762623003.7838924,"logger":"tls.cache.maintenance","msg":"error while checking if stored certificate is also expiring soon","identifiers":["*.xd003.cc"],"error":"open /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.key: no such file or directory"}
caddy  | {"level":"info","ts":1762623003.7839081,"logger":"tls.cache.maintenance","msg":"certificate expires soon; queuing for renewal","identifiers":["*.xd003.cc"],"remaining":-7173985.783907388}
caddy  | {"level":"error","ts":1762623004.850977,"logger":"tls.renew","msg":"will retry","error":"open /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.key: no such file or directory","attempt":5,"retrying_in":600,"elapsed":600.009836933,"max_duration":2592000}
caddy  | {"level":"info","ts":1762623603.785847,"logger":"tls","msg":"certificate needs renewal based on ARI window","subjects":["*.xd003.cc"],"expiration":1755449018,"ari_cert_id":"nytfzzwhT50Et-0rLMTGcIvS1w0.BWow56lX8w9SayBINRC9oP8M","next_ari_update":1762644004.8367982,"renew_check_interval":600,"window_start":1752780462,"window_end":1752935911,"selected_time":1752907091,"renewal_cutoff":1752906491}
caddy  | {"level":"warn","ts":1762623603.785972,"logger":"tls.cache.maintenance","msg":"error while checking if stored certificate is also expiring soon","identifiers":["*.xd003.cc"],"error":"open /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.key: no such file or directory"}
caddy  | {"level":"info","ts":1762623603.7859921,"logger":"tls.cache.maintenance","msg":"certificate expires soon; queuing for renewal","identifiers":["*.xd003.cc"],"remaining":-7174585.785991624}
caddy  | {"level":"error","ts":1762623604.8519735,"logger":"tls.renew","msg":"will retry","error":"open /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.key: no such file or directory","attempt":6,"retrying_in":600,"elapsed":1200.010832805,"max_duration":2592000}
caddy  | {"level":"info","ts":1762624203.7838001,"logger":"tls","msg":"certificate needs renewal based on ARI window","subjects":["*.xd003.cc"],"expiration":1755449018,"ari_cert_id":"nytfzzwhT50Et-0rLMTGcIvS1w0.BWow56lX8w9SayBINRC9oP8M","next_ari_update":1762644004.8367982,"renew_check_interval":600,"window_start":1752780462,"window_end":1752935911,"selected_time":1752907091,"renewal_cutoff":1752906491}
caddy  | {"level":"warn","ts":1762624203.783941,"logger":"tls.cache.maintenance","msg":"error while checking if stored certificate is also expiring soon","identifiers":["*.xd003.cc"],"error":"open /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.key: no such file or directory"}
caddy  | {"level":"info","ts":1762624203.7839587,"logger":"tls.cache.maintenance","msg":"certificate expires soon; queuing for renewal","identifiers":["*.xd003.cc"],"remaining":-7175185.783958192}
caddy  | {"level":"error","ts":1762624204.8529706,"logger":"tls.renew","msg":"will retry","error":"open /data/caddy/certificates/acme-v02.api.letsencrypt.org-directory/wildcard_.xd003.cc/wildcard_.xd003.cc.key: no such file or directory","attempt":7,"retrying_in":600,"elapsed":1800.011830444,"max_duration":2592000}

3. Caddy version:

2.10.2

4. How I installed and ran Caddy:

I am using Caddy in a docker container

a. System environment:

OS: Linux (Ubuntu 25.04)
architecture: arm64
Docker version 28.3.3, build 980b856

b. Command:

docker compose up -d

c. Service/unit/compose file:

services:
  caddy:
    image: ghcr.io/xd003/caddy:latest
    container_name: caddy
    restart: unless-stopped
    networks:
      - proxy
    cap_add:
      - NET_ADMIN    
    extra_hosts:
      - "host.docker.internal:host-gateway"
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - caddy_logs:/var/log/caddy
      - caddy_data:/data
      - caddy_config:/config
      - ./Caddyfile:/etc/caddy/Caddyfile
    env_file:
      - .env
      
networks:
  proxy:
    external: true
    name: proxy
    
volumes:
  caddy_logs:
  caddy_data:
  caddy_config:

d. My complete Caddy config:

{
    email {$EMAIL}
}

*.{$DOMAIN} {
    tls {
        dns cloudflare {$CLOUDFLARE_API_TOKEN}
	resolvers 1.1.1.1 8.8.8.8
    }
}

5. Links to relevant resources:

It looks like Caddy deleted the old wildcard certificate and key (since it was past the grace period) but is now failing to renew it, possibly because the key file it expects doesn’t exist anymore.

The issue got resolved after redeploying the container, i wonder why it even occured in first place, caddy should have handled it internally when it occured

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.