Just recently, I started seeing problems where one Let's Encrypt certificate
was not being renewed by acme-client.
Digging around the issue after waiting a few days to see if the issue as
temporal, I found that the temporary file set by acme-client in
/var/www/acme/ is not available when Let's Encrypt checks for it; instead,
httpd is generating a 404.
I'm running 7.9
$ uname -a
OpenBSD www 7.9 GENERIC#8 amd64
Relevant portions of /etc/acme-client.conf
------------------------------------------
authority letsencrypt-staging {
api url "https://acme-staging-v02.api.letsencrypt.org/directory"
account key "/etc/acme/letsencrypt-staging-privkey.pem" }
domain www.example.com {
domain key "/etc/ssl/private/www.example.com.key.pem"
domain full chain certificate "/etc/ssl/certs/www.example.com.chain.pem"
sign with letsencrypt-staging
}
Relevant parts of httpd.conf
----------------------------
server "www.example.com" {
alias "www2.example.com"
listen on 203.0.113.1 port 80
listen on 3fff:a:b::2 port 80
location "/.well-known/acme-challenge/*" {
root "/acme"
request strip 2
pass
}
block return 301 "https://$HTTP_HOST$REQUEST_URI"
}
Here is a breakdown of the transaction; running acme-client shows the error:
# acme-client -v www.example.com
acme-client: https://acme-staging-v02.api.letsencrypt.org/directory: directories
acme-client: acme-staging-v02.api.letsencrypt.org: DNS: 172.65.46.172
acme-client: acme-staging-v02.api.letsencrypt.org: DNS:
2606:4700:60:0:f41b:d4fe:4325:6026
acme-client: account key:
https://acme-staging-v02.api.letsencrypt.org/acme/acct/999999999
acme-client: dochngreq:
https://acme-staging-v02.api.letsencrypt.org/acme/authz/999999999/4323610543
acme-client: challenge, token: 0qew5-cCl8MYLRX1I58Ald50lxppE4yM0RZy-aeJRUQ,
uri:
https://acme-staging-v02.api.letsencrypt.org/acme/chall/999999999/4323610543/MtUOoQ,
status: 0
acme-client: /var/www/acme/0qew5-cCl8MYLRX1I58Ald50lxppE4yM0RZy-aeJRUQ: created
acme-client:
https://acme-staging-v02.api.letsencrypt.org/acme/chall/999999999/4323610543/MtUOoQ:
challenge
acme-client: order.status 0
acme-client: dochngreq:
https://acme-staging-v02.api.letsencrypt.org/acme/authz/999999999/4323610543
acme-client: challenge, token: 0qew5-cCl8MYLRX1I58Ald50lxppE4yM0RZy-aeJRUQ,
uri:
https://acme-staging-v02.api.letsencrypt.org/acme/chall/999999999/4323610543/MtUOoQ,
status: 0
acme-client: /var/www/acme/0qew5-cCl8MYLRX1I58Ald50lxppE4yM0RZy-aeJRUQ: created
acme-client:
https://acme-staging-v02.api.letsencrypt.org/acme/chall/999999999/4323610543/MtUOoQ:
challenge
acme-client:
https://acme-staging-v02.api.letsencrypt.org/acme/chall/999999999/4323610543/MtUOoQ:
bad HTTP: 409
acme-client: transfer buffer: [{
"type": "urn:ietf:params:acme:error:conflict",
"detail": "Unable to update challenge :: failed to mark authz as processing:
Authorization is already being validated. This may indicate your client
attempted the same challenge multiple times, possibly due to a client bug.",
"status": 409
}] (296 bytes)
acme-client: bad exit: netproc(58779): 1
Looking at the output that LE provides at the following URL shows an HTTP
404 when trying to fetch the challenge file.
<https://acme-staging-v02.api.letsencrypt.org/acme/authz/999999999/4322736873>
{
"identifier": {
"type": "dns",
"value": "www.example.com"
},
"status": "invalid",
"expires": "2026-09-10T14:03:56Z",
"challenges": [
{
"type": "http-01",
"url":
"https://acme-staging-v02.api.letsencrypt.org/acme/chall/999999999/4323610543/MtUOoQ",
"status": "invalid",
"validated": "2026-09-03T14:03:57Z",
"error": {
"type": "urn:ietf:params:acme:error:unauthorized",
"detail": "203.0.113.1: Invalid response from
http://www.example.com/.well-known/acme-challenge/0qew5-cCl8MYLRX1I58Ald50lxppE4yM0RZy-aeJRUQ:
404",
"status": 403
},
"token": "0qew5-cCl8MYLRX1I58Ald50lxppE4yM0RZy-aeJRUQ",
"validationRecord": [
{
"url":
"http://www.example.com/.well-known/acme-challenge/0qew5-cCl8MYLRX1I58Ald50lxppE4yM0RZy-aeJRUQ",
"hostname": "www.example.com",
"port": "80",
"addressesResolved": [
"3fff:a:b::2",
"203.0.113.1"
],
"addressUsed": "3fff:a:b::2"
},
{
"url":
"http://www.example.com/.well-known/acme-challenge/0qew5-cCl8MYLRX1I58Ald50lxppE4yM0RZy-aeJRUQ",
"hostname": "www.example.com",
"port": "80",
"addressesResolved": [
"3fff:a:b::2",
"203.0.113.1"
],
"addressUsed": "203.0.113.1"
}
]
}
]
}
So there is definitely a 404 occuring, but the file DOES exist in
/var/www/acme/ (as shown during the time of the transaction)
# find /var/www/acme -ls
155520 4 drwxr-xr-x 2 root daemon 512 Sep 3 09:03
/var/www/acme
155521 4 -r--r--r-- 1 root daemon 87 Sep 3 09:04
/var/www/acme/0qew5-cCl8MYLRX1I58Ald50lxppE4yM0RZy-aeJRUQ
/var/www/logs/access.log shows the HTTP 404 being served.
www.example.com 66.133.109.36 - - [03/Sep/2026:09:04:07 -0500] "GET
/.well-known/acme-challenge/0qew5-cCl8MYLRX1I58Ald50lxppE4yM0RZy-aeJRUQ
HTTP/1.1" 404 0
Is anyone else experiencing this issue? What have you done to work around it?
Thanks in advance.