[GH-ISSUE #318] Acme DNS can issue only 1 subdomain #173

Open
opened 2026-03-13 16:02:29 +03:00 by kerem · 2 comments
Owner

Originally created by @b-a-t on GitHub (Oct 10, 2022).
Original GitHub issue: https://github.com/acme-dns/acme-dns/issues/318

I would like to bring attention to the issue described in the acme.sh repo - https://github.com/acmesh-official/acme.sh/issues/4221

In short, acme-dns for whatever reason limits the number of TXT records in the air to two, which creates trouble issuing and renewing certificates with 3 or more SAN records.

The mentioned issue provides a workaround for this limitation, but I believe it is better to be fixed in the acme-dns itself.

This https://github.com/acmesh-official/acme.sh/issues/4221#issuecomment-1207433691 has a more detailed description of the problem:

The problem with that solution is that you'll need to update your _acme-challenge CNAME record every time you renew (!) and that it'll create a new user account every single time you renew for every subdomain. In your case, after 4 renewals, you'll end up with 12 accounts on the acme-dns server, 9 of them unused.

The cause of this problem is as follows:

* acme-dns https://github.com/joohoi/acme-dns/issues/233#issuecomment-650365900 to only ever return two verification TXT-records per account.
* acme.sh uses a single account to talk to acme-dns's API per certificate (this used to be 1 account globally).
* acme.sh uses acme-dns's API to add all TXT records at the same time.
* if you only verify -d example.com -d www.example.com, two is enough.
* if you only verify -d example.com -d *.example.com, two is enough.
* -d example.com -d foo.example.com -d bar.example.com is one too many. One is silently discarded.
* acme.sh asks the issuer (ZeroSSL / Let's Encrypt / etc) to verify. It only sees two TXT records, so one domain fails.

As credentials are saved per certificate, using multiple config-home directories won't help.

This problem has come up before, but so far I don't think anyone has tackled this issue. It's not specific to subdomains: -d example.com -d example.org -d example.net would cause this, too.

Solutions to this might be:

1. Add one TXT record, verify, and then add the next one. I don't think this is feasible with acme.sh.
2. Add all TXT records, but mod acme-dns to allow more records. There are some forks, but it goes against acme-dns's design. acme.sh's dns_acmedns.sh file also assumes a limit of 2 records: dns_acmedns_rm() is blank as there's no real reason to clean up after itself.
3. Save account credentials per domain, per certificate.

The last option will require some development work and some time testing. I've attached a quick extension to dns_acmedns.sh but it doesn't include automatic registration or saving credentials. You'll need to do both manually.

Originally created by @b-a-t on GitHub (Oct 10, 2022). Original GitHub issue: https://github.com/acme-dns/acme-dns/issues/318 I would like to bring attention to the issue described in the `acme.sh` repo - https://github.com/acmesh-official/acme.sh/issues/4221 In short, `acme-dns` for whatever reason limits the number of TXT records in the air to two, which creates trouble issuing and renewing certificates with 3 or more SAN records. The mentioned issue provides a workaround for this limitation, but I believe it is better to be fixed in the `acme-dns` itself. This https://github.com/acmesh-official/acme.sh/issues/4221#issuecomment-1207433691 has a more detailed description of the problem: > The problem with that solution is that you'll need to update your _acme-challenge CNAME record every time you renew (!) and that it'll create a new user account every single time you renew for every subdomain. In your case, after 4 renewals, you'll end up with 12 accounts on the acme-dns server, 9 of them unused. > > The cause of this problem is as follows: > > * acme-dns https://github.com/joohoi/acme-dns/issues/233#issuecomment-650365900 to only ever return two verification TXT-records per account. > * acme.sh uses a single account to talk to acme-dns's API per certificate (this used to be 1 account globally). > * acme.sh uses acme-dns's API to add all TXT records at the same time. > * if you only verify -d example.com -d www.example.com, two is enough. > * if you only verify -d example.com -d *.example.com, two is enough. > * -d example.com -d foo.example.com -d bar.example.com is one too many. One is silently discarded. > * acme.sh asks the issuer (ZeroSSL / Let's Encrypt / etc) to verify. It only sees two TXT records, so one domain fails. > > As credentials are saved per certificate, using multiple config-home directories won't help. > > This problem has come up before, but so far I don't think anyone has tackled this issue. It's not specific to subdomains: -d example.com -d example.org -d example.net would cause this, too. > > Solutions to this might be: > > 1. Add one TXT record, verify, and then add the next one. I don't think this is feasible with acme.sh. > 2. Add all TXT records, but mod acme-dns to allow more records. There are some forks, but it goes against acme-dns's design. acme.sh's dns_acmedns.sh file also assumes a limit of 2 records: dns_acmedns_rm() is blank as there's no real reason to clean up after itself. > 3. Save account credentials per domain, per certificate. > > The last option will require some development work and some time testing. I've attached a quick extension to dns_acmedns.sh but it doesn't include automatic registration or saving credentials. You'll need to do both manually.
Author
Owner

@kkloesener commented on GitHub (Dec 31, 2023):

Depending on your Use Case there is another solution. This solution makes the world even more secure:

If your server supports SNI don’t use SAN certificates at all and just issue additional certificates to use them.

All current reverse-proxy and load-balancer like Traefik, nginx, Citrix Netscaler, kemp and f5 support this for HTTPS

<!-- gh-comment-id:1872902931 --> @kkloesener commented on GitHub (Dec 31, 2023): Depending on your Use Case there is another solution. This solution makes the world even more secure: If your server supports [SNI](https://knowledge.digicert.com/quovadis/ssl-certificates/ssl-general-topics/what-is-sni-server-name-indication.html) don’t use SAN certificates at all and just issue additional certificates to use them. All current reverse-proxy and load-balancer like Traefik, nginx, Citrix Netscaler, kemp and f5 support this for HTTPS
Author
Owner

@TomyLobo commented on GitHub (Dec 8, 2025):

fwiw, here's the culprit:
https://github.com/joohoi/acme-dns/blob/v1.1/db.go#L256

And no, splitting up the certs, like @kkloesener suggests, doesn't help, at least not on its own, and I don't see how it would add any security, since you're still keeping all the certs in the same place.
You have to use separate acme-dns accounts to work around this issue.

Unfortunately, acme.sh doesn't support setting an acme-dns account per hostname.
certbot might be able to do it or not, I haven't looked into it.
So you might still need to split up the certs anyway, in addition to using separate accounts.

cert-manager should be able to do it, but that's rather kubernetes-specific.
It handles all challenges separately and its acme-dns config is keyed by hostname.
So it should work. Should.

<!-- gh-comment-id:3626630252 --> @TomyLobo commented on GitHub (Dec 8, 2025): fwiw, here's the culprit: https://github.com/joohoi/acme-dns/blob/v1.1/db.go#L256 And no, splitting up the certs, like @kkloesener suggests, doesn't help, at least not on its own, and I don't see how it would add any security, since you're still keeping all the certs in the same place. You have to use separate acme-dns accounts to work around this issue. Unfortunately, acme.sh doesn't support setting an acme-dns account per hostname. certbot might be able to do it or not, I haven't looked into it. So you might still need to split up the certs anyway, _in addition_ to using separate accounts. cert-manager _should_ be able to do it, but that's rather kubernetes-specific. It handles all challenges separately and its acme-dns config is keyed by hostname. So it _should_ work. _Should_.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/acme-dns#173
No description provided.