I'm using pfSense with ACME for LE certificates. It has always worked well. My domains DNS is hosted via Linode so I have used Linode's API for domain validation. This has always worked.
I have a new wildcard certificate I'd like to generate: *.chd.xavs.it. I have other wildcard certificates which I have been able to renew without issue today. However, despite making a copy of the settings of existing working wildcard certificates, this one does not get issued.
Looking at the logs produced, I have this:
wildcard.chd.xavs.it
Renewing certificate
account: ACME-prod
server: letsencrypt-production-2
/usr/local/pkg/acme/acme.sh --issue --domain '*.chd.xavs.it' --dns 'dns_linode_v4' --home '/tmp/acme/wildcard.chd.xavs.it/' --accountconf '/tmp/acme/wildcard.chd.xavs.it/accountconf.conf' --force --always-force-new-domain-key --reloadCmd '/tmp/acme/wildcard.chd.xavs.it/reloadcmd.sh' --dnssleep '30' --log-level 3 --log '/tmp/acme/wildcard.chd.xavs.it/acme_issuecert.log'
Array
(
[path] => /etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin/
[PATH] => /etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin/
[SSL_CERT_DIR] => /etc/ssl/certs/
[LINODE_V4_API_KEY] => b6c254c89-redacted-4796e4
)
[Mon Mar 10 17:54:41 GMT 2025] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Mon Mar 10 17:54:41 GMT 2025] Using pre generated key: /tmp/acme/wildcard.chd.xavs.it/*.chd.xavs.it/*.chd.xavs.it.key.next
[Mon Mar 10 17:54:41 GMT 2025] Generate next pre-generate key.
[Mon Mar 10 17:54:42 GMT 2025] Single domain='*.chd.xavs.it'
[Mon Mar 10 17:54:44 GMT 2025] Getting webroot for domain='*.chd.xavs.it'
[Mon Mar 10 17:54:44 GMT 2025] Adding txt value: IaQzHBbTBRLJIruNDhoXhwbhG0PaQhz__Enda6CDoVA for domain: _acme-challenge.chd.xavs.it
[Mon Mar 10 17:54:44 GMT 2025] Using Linode
[Mon Mar 10 17:54:44 GMT 2025] Domain resource successfully added.
[Mon Mar 10 17:54:44 GMT 2025] The txt record is added: Success.
[Mon Mar 10 17:54:44 GMT 2025] Sleep 30 seconds for the txt records to take effect
[Mon Mar 10 17:55:14 GMT 2025] Verifying: *.chd.xavs.it
[Mon Mar 10 17:55:15 GMT 2025] Pending, The CA is processing your order, please just wait. (1/30)
[Mon Mar 10 17:55:17 GMT 2025] Removing DNS records.
[Mon Mar 10 17:55:18 GMT 2025] Removing txt: IaQzHBbTBRLJIruNDhoXhwbhG0PaQhz__Enda6CDoVA for domain: _acme-challenge.chd.xavs.it
[Mon Mar 10 17:55:18 GMT 2025] Using Linode
[Mon Mar 10 17:55:18 GMT 2025] Domain resource successfully deleted.
[Mon Mar 10 17:55:18 GMT 2025] Removed: Success
[Mon Mar 10 17:55:17 GMT 2025] Invalid status, *.chd.xavs.it:Verify error detail:No TXT record found at _acme-challenge.chd.xavs.it
[Mon Mar 10 17:55:18 GMT 2025] Please check log file for more details: /tmp/acme/wildcard.chd.xavs.it/acme_issuecert.log
The strange thing is that having just done it for another wildcard (renewal as it already existed), it succeeds and produces similar logs:
wildcard.rdg.xavs.it
Renewing certificate
account: ACME-prod
server: letsencrypt-production-2
/usr/local/pkg/acme/acme.sh --issue --domain '*.rdg.xavs.it' --dns 'dns_linode_v4' --home '/tmp/acme/wildcard.rdg.xavs.it/' --accountconf '/tmp/acme/wildcard.rdg.xavs.it/accountconf.conf' --force --always-force-new-domain-key --reloadCmd '/tmp/acme/wildcard.rdg.xavs.it/reloadcmd.sh' --log-level 3 --log '/tmp/acme/wildcard.rdg.xavs.it/acme_issuecert.log'
Array
(
[path] => /etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin/
[PATH] => /etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin/
[SSL_CERT_DIR] => /etc/ssl/certs/
[LINODE_V4_API_KEY] => 48271f78767-redacted-7be04324
)
[Mon Mar 10 17:52:31 GMT 2025] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Mon Mar 10 17:52:31 GMT 2025] Using pre generated key: /tmp/acme/wildcard.rdg.xavs.it/*.rdg.xavs.it/*.rdg.xavs.it.key.next
[Mon Mar 10 17:52:31 GMT 2025] Generate next pre-generate key.
[Mon Mar 10 17:52:31 GMT 2025] Single domain='*.rdg.xavs.it'
[Mon Mar 10 17:52:33 GMT 2025] Getting webroot for domain='*.rdg.xavs.it'
[Mon Mar 10 17:52:33 GMT 2025] Adding txt value: gC5w0O5RgH6z-SLs8IvQ-uimVPerEWekH4ro5SxyL3A for domain: _acme-challenge.rdg.xavs.it
[Mon Mar 10 17:52:33 GMT 2025] Using Linode
[Mon Mar 10 17:52:34 GMT 2025] Domain resource successfully added.
[Mon Mar 10 17:52:34 GMT 2025] The txt record is added: Success.
[Mon Mar 10 17:52:34 GMT 2025] Let's check each DNS record now. Sleep 20 seconds first.
[Mon Mar 10 17:53:58 GMT 2025] Verifying: *.rdg.xavs.it
[Mon Mar 10 17:53:58 GMT 2025] Pending, The CA is processing your order, please just wait. (1/30)
[Mon Mar 10 17:54:01 GMT 2025] Success
[Mon Mar 10 17:54:01 GMT 2025] Removing DNS records.
[Mon Mar 10 17:54:01 GMT 2025] Removing txt: gC5w0O5RgH6z-SLs8IvQ-uimVPerEWekH4ro5SxyL3A for domain: _acme-challenge.rdg.xavs.it
[Mon Mar 10 17:54:01 GMT 2025] Using Linode
[Mon Mar 10 17:54:01 GMT 2025] Domain resource successfully deleted.
[Mon Mar 10 17:54:01 GMT 2025] Removed: Success
[Mon Mar 10 17:54:02 GMT 2025] Verify finished, start to sign.
[Mon Mar 10 17:54:02 GMT 2025] Lets finalize the order.
Comparing the logs, it looks like when it succeeds, I get a Success after the Pending, The CA is processing your order, please just wait. (1/30) entry. When it fails, I do not get the Success.
I can see in Linode the API key generated (and then deleted) and everything else is the same as far as I can see.
Thanks for the quick response, Mike.
I don't think it's that. I had truncated the response on the one that worked as that didn't have any wait time whereas the one that failed had some.
I've tried increasing to 40 seconds, but it makes no difference:
wildcard.chd.xavs.it
Renewing certificate
account: ACME-prod
server: letsencrypt-production-2
/usr/local/pkg/acme/acme.sh --issue --domain '*.chd.xavs.it' --dns 'dns_linode_v4' --home '/tmp/acme/wildcard.chd.xavs.it/' --accountconf '/tmp/acme/wildcard.chd.xavs.it/accountconf.conf' --force --always-force-new-domain-key --reloadCmd '/tmp/acme/wildcard.chd.xavs.it/reloadcmd.sh' --dnssleep '40' --log-level 3 --log '/tmp/acme/wildcard.chd.xavs.it/acme_issuecert.log'
Array
(
[path] => /etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin/
[PATH] => /etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin/
[SSL_CERT_DIR] => /etc/ssl/certs/
[LINODE_V4_API_KEY] => -redacted-
)
[Mon Mar 10 18:50:10 GMT 2025] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Mon Mar 10 18:50:10 GMT 2025] Using pre generated key: /tmp/acme/wildcard.chd.xavs.it/*.chd.xavs.it/*.chd.xavs.it.key.next
[Mon Mar 10 18:50:10 GMT 2025] Generate next pre-generate key.
[Mon Mar 10 18:50:10 GMT 2025] Single domain='*.chd.xavs.it'
[Mon Mar 10 18:50:12 GMT 2025] Getting webroot for domain='*.chd.xavs.it'
[Mon Mar 10 18:50:12 GMT 2025] Adding txt value: x5OcZMBokNidJIxPASgI_kszc9faRNY4uElhmxpk88M for domain: _acme-challenge.chd.xavs.it
[Mon Mar 10 18:50:12 GMT 2025] Using Linode
[Mon Mar 10 18:50:13 GMT 2025] Domain resource successfully added.
[Mon Mar 10 18:50:13 GMT 2025] The txt record is added: Success.
[Mon Mar 10 18:50:13 GMT 2025] Sleep 40 seconds for the txt records to take effect
[Mon Mar 10 18:50:53 GMT 2025] Verifying: *.chd.xavs.it
[Mon Mar 10 18:50:54 GMT 2025] Pending, The CA is processing your order, please just wait. (1/30)
[Mon Mar 10 18:50:56 GMT 2025] Removing DNS records.
[Mon Mar 10 18:50:56 GMT 2025] Removing txt: x5OcZMBokNidJIxPASgI_kszc9faRNY4uElhmxpk88M for domain: _acme-challenge.chd.xavs.it
[Mon Mar 10 18:50:56 GMT 2025] Using Linode
[Mon Mar 10 18:50:57 GMT 2025] Domain resource successfully deleted.
[Mon Mar 10 18:50:57 GMT 2025] Removed: Success
[Mon Mar 10 18:50:56 GMT 2025] Invalid status, *.chd.xavs.it:Verify error detail:No TXT record found at _acme-challenge.chd.xavs.it
[Mon Mar 10 18:50:57 GMT 2025] Please check log file for more details: /tmp/acme/wildcard.chd.xavs.it/acme_issuecert.log
Feel a little silly, having now set to 90 seconds, it's worked.
The strange thing is that on the other wildcard where the renewal worked, there was no DNS sleep time set at all, yet it renewed instantly without any problem.
No, there was not because it did its own check that the TXT record had the right value before telling the Let's Encrypt cert it was ready. And, that took 1m24s. It did not need an explicit sleep time because it actually checked the TXT value first.
The failed one only did a sleep. So, it has to sleep long enough to handle the worst case. I doubt 90s is sufficient given what we saw in that other one. Sure, it may work sometimes, and did, but at least twice that would be better. The best solution would be to figure out how to enable the pre-check. I didn't look at the acme.sh docs about that but these are common techniques to deal with DSN Challenge TXT values.
It's interesting.
Having just tried to renew the newly created certificate without any sleep time and it's worked!
wildcard.chd.xavs.it
Renewing certificate
account: ACME-prod
server: letsencrypt-production-2
/usr/local/pkg/acme/acme.sh --issue --domain '*.chd.xavs.it' --dns 'dns_linode_v4' --home '/tmp/acme/wildcard.chd.xavs.it/' --accountconf '/tmp/acme/wildcard.chd.xavs.it/accountconf.conf' --force --always-force-new-domain-key --reloadCmd '/tmp/acme/wildcard.chd.xavs.it/reloadcmd.sh' --log-level 3 --log '/tmp/acme/wildcard.chd.xavs.it/acme_issuecert.log'
Array
(
[path] => /etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin/
[PATH] => /etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin/
[SSL_CERT_DIR] => /etc/ssl/certs/
[LINODE_V4_API_KEY] => -redacted-
)
[Mon Mar 10 22:43:03 GMT 2025] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Mon Mar 10 22:43:03 GMT 2025] Using pre generated key: /tmp/acme/wildcard.chd.xavs.it/*.chd.xavs.it/*.chd.xavs.it.key.next
[Mon Mar 10 22:43:03 GMT 2025] Generate next pre-generate key.
[Mon Mar 10 22:43:03 GMT 2025] Single domain='*.chd.xavs.it'
[Mon Mar 10 22:43:05 GMT 2025] Getting webroot for domain='*.chd.xavs.it'
[Mon Mar 10 22:43:05 GMT 2025] *.chd.xavs.it is already verified, skip dns-01.
[Mon Mar 10 22:43:05 GMT 2025] Verify finished, start to sign.
[Mon Mar 10 22:43:05 GMT 2025] Lets finalize the order.
[Mon Mar 10 22:43:05 GMT 2025] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/99754610/362251613816'
[Mon Mar 10 22:43:07 GMT 2025] Downloading cert.
[Mon Mar 10 22:43:07 GMT 2025] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/03e29906745ed4f4e8e9600b92bf350119cc'
[Mon Mar 10 22:43:07 GMT 2025] Cert success.
I'm wondering if when it's renewing, it has a local txt record cached so uses that. Or rather that it remembers that the DNS name has already been verified so it doesn't need to do it. Whereas when creating from new, it has to create the txt record at the DNS server level.
I've just noticed this because when I renew, I don't get any notification from Linode that any txt entries were created then deleted. And it's not created because the log suggests [Mon Mar 10 22:43:05 GMT 2025] *.chd.xavs.it is already verified, skip dns-01. But if I create a new DNS record for which there has never been a certificate, then the ACME process does create a temporary txt record, and in that instance, it needs longer to do the whole DNS verification.
What puzzles me is that I never had to put in a sleep time before when creating brand new certificates, it always just worked. Now, it appears that I have to add at least those 90 seconds for it to work Maybe something has changed in ACME.
Anyway, thanks for your prompt answers, I'm good for now, even if I'm still not quite sure why it worked before on new certs without the sleep...
Let's Encrypt will reuse the previously validated authorizations, which are cached for 30 days (currently). As shown by the "*.chd.xavs.it is already verified, skip dns-01" part of your log.
Yes, the latter. Let's Encrypt caches successful validations for 30 days (currently). So, there was no reason for it to do a fresh challenge at all. See: FAQ - Let's Encrypt
Some ACME Clients have test modes to invalidate that cache so you get a "full and proper" test. I am not sure if or how acme.sh does that.
No, nothing that would explain what you say. Possibly acme.sh or the DNS plugin you use changed default config settings. Or, maybe your new setup uses a different set of default options.