Making a certificate for a base domain plus its wildcard "in one" creates two TXT records, overwriting the first one, breaking the challenge ("During secondary validation: Incorrect TXT record")

Please fill out the fields below so we can help you better. Note: you must provide your domain name to get help. Domain names for issued certificates are all made public in Certificate Transparency logs (e.g. crt.sh | example.com), so withholding your domain name here does not increase secrecy, but only makes it harder for us to provide help.

On my primary domain I ran `certbot certonly --agree-tos --manual --preferred-challenge=dns --manual-auth-hook=./letsencrypt-dns-hook -d '*.mydomain.au' -d 'mydomain.au'

certbot asked if I want to (E)xtend the existing wildcard certificate to include the base domain (My goal), and I hit (E) to say yes. Then it errored with During secondary validation: Incorrect TXT record. I noticed that certbot wrote two TXT records before validating the first one, causing the first TXT record to get overwritten, failing the challenge.

So I ran the exact same command again and this time it worked? This person from 2018 had the same experience on their second run: Update wildcard certificate to include base domain - #6 by PeterC

So okay, now I want to do the same thing for another domain of mine wildcard plus base domain in one cert. This second domain doesn't have any cert yet.

So I ran the exact same command for my other domain which does not have a wildcard cert of its own yet: ``certbot certonly --agree-tos --manual --preferred-challenge=dns --manual-auth-hook=./letsencrypt-dns-hook -d '*.seconddomain.au' -d 'seconddomain.au'`

No matter what, certbot always attempts to create two TXT records, overwriting whatever one it makes first, causing the challenge to fail. Unlike (E)xtending like I was able to do with my existing wildcard cert on the first domain, this domain has no existing one to extend. Running the command a second time still attempts to create two records. I can't seem to convey to certbot that this is supposed to be a single certificate valid for both the base domain and its wildcard.

I managed to work around this problem by making a wildcard cert for that second domain first, then running the same command again with and additional -d for its base domain on the end and selecting the (E)xtend option.

Strange how this is still the default behavior for over 8 years.

This is the problem with Manual DNS as a way to validate your domain. The wildcard *.domain.com and the apex domain.com share the same _acme-challenge record. So you either need to give it two values or complete validation for one at a time.

It's not a certbot fault, it's the ACME protocol that requires that particular quirk.

Ideally use an automated DNS provider for DNS challenges instead of doing manual updates.

4 Likes

It isn't actually Certbot doing that but your manual DNS plugin script that does that.

Other DNS providers allow multiple TXT record values to be outstanding for the same name. In fact, this is very common.

And, it isn't specific to the --manual method either. If your DNS system allows it you can type in multiple values for the same record. Although, manually typing entries doesn't allow automation.

Perhaps your DNS script could be updated to first read the existing record(s) before adding a new value?

The work-around you saw, and use, relies on Let's Encrypt caching successful challenges. Your first pass with just one domain succeeds and LE caches that result. Your second attempt with one extra domain name succeeds because only one new challenge is required.

You have a number of options. Switch to a DNS provider that is supported by a better DNS automation option. Either one supported by Certbot (like Cloudflare) or just with a better API and/or script for multiple values.

Maybe your existing DNS provider already supports multiple values with its API but that script doesn't do it right. If that's the case perhaps a different ACME Client might have better DNS API support for your system. You didn't provide your domain so I can't say for sure. But, look at an ACME Client like lego: GitHub - go-acme/lego: Let's Encrypt/ACME client and library written in Go

5 Likes