macOS Server: "Incorrect validation certificate for tls-sni-01 challenge"

My domain is enchanter.net. My server www.enchanter.net is running macOS 10.12.5 / Apache 2.4.25. I have root shell access. I manage the site through the Apple macOS “Server” application.

When I run “certbot --apache”, it first says:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
No names were found in your configuration files. Please enter in your domain
name(s) (comma and/or space separated)  (Enter 'c' to cancel):

I enter “enchanter.net”, then it tells me:

Obtaining a new certificate
Performing the following challenges:
tls-sni-01 challenge for enchanter.net
No vhost exists with servername or alias of: enchanter.net (or it's in a file with multiple vhosts, which Certbot can't parse yet). No vhost was selected. Please specify ServerName or ServerAlias in the Apache config, or split vhosts into separate files.
Falling back to default vhost *:443...
Waiting for verification...
Cleaning up challenges
Failed authorization procedure. enchanter.net (tls-sni-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Incorrect validation certificate for tls-sni-01 challenge. Requested ebfb020d0519b55ba71073ccafd485e1.4e7a80f24bc205837607a89600ced14b.acme.invalid from 216.53.249.115:443. Received 2 certificate(s), first certificate had names "www.enchanter.net"

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: enchanter.net
   Type:   unauthorized
   Detail: Incorrect validation certificate for tls-sni-01 challenge.
   Requested
   ebfb020d0519b55ba71073ccafd485e1.4e7a80f24bc205837607a89600ced14b.acme.invalid
   from 216.53.249.115:443. Received 2 certificate(s), first
   certificate had names "www.enchanter.net"

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A record(s) for that domain
   contain(s) the right IP address.

Same thing happens if I enter “www.enchanter.net” as the domain.

My DNS A record for this domain has the correct IP address. And I do have ServerAlias entries set up in the config files:

$ grep ServerAlias /Library/Server/Web/Config/apache2/sites/*.conf
/Library/Server/Web/Config/apache2/sites/0000_127.0.0.1_34543_.conf:	ServerAlias enchanter.net
/Library/Server/Web/Config/apache2/sites/0000_127.0.0.1_34580_.conf:	ServerAlias enchanter.net

Anyone have any suggestions? Are there other ways to configure this that I should fall back to? I don’t see many reports of people using it on macOS.

My suspicion is that since my https instance is using a self-signed certificate right now, maybe that’s failing whatever test certbot uses.

Hi @bkendig,

It's unlikely that the failure has anything to do with your self-signed certificate. Certbot is attempting to configure Apache to temporarily serve a specific Certbot-generated certificate in response to the certificate authority's challenge, yet is failing to do so.

The failure is almost definitely related to the error message

No vhost exists with servername or alias of: enchanter.net (or it's in a file with multiple vhosts, which Certbot can't parse yet). No vhost was selected. Please specify ServerName or ServerAlias in the Apache config, or split vhosts into separate files.

Is it possible that the configuration file that defines that virtual host contains multiple virtual hosts in the same file?

If not, do you think you could post your Apache configuration files here?

Thank you for the pointer. It may be entirely possible that that bit about “a file with multiple vhosts” is what’s causing trouble, because as I try to decipher the way that macOS Server sets things up, it looks like I have:

  • an httpd instance using /Library/Server/Web/Config/Proxy/apache_serviceproxy.conf, which defines a VirtualHost for port 80 and another for port 443, and each of these VirtualHosts proxies to a different port
  • another httpd instance using /Library/Server/Web/Config/apache2/httpd_server_app.conf, which loads individual files from /Library/Server/Web/Config/apache2/sites for each individual site and handles the ports forwarded to it from the above instance

At first I was only aware of the second one of these, but the first one is definitely what runs afoul of that limitation.

I don’t want to muck with the configuration too much because that might confuse the Server app.

What’s the best way for me to proceed, to get and maintain a Let’s Encrypt certificate for my port 443 instance? If there’s a way for me to get the certificate some other way, I can easily use the Server app to add it to my site.

Sorry about that, it's definitely a known bug in Certbot because the multiple virtualhosts per file is permitted by Apache.

You might have better luck with --webroot, which doesn't need to reconfigure your webserver but just creates a file on your site to prove that you control the domain name.

If you just want the certificate and don't want Certbot to try to install it into Apache for you:

certbot certonly --webroot -w /wherever/your/web/content/goes -d enchanter.net -d www.enchanter.net

If you want Certbot to try to install it as well (which may also not work because of the multiple virtual hosts in a single file):

certbot -a webroot -i apache -w /wherever/your/web/content/goes -d enchanter.net -d www.enchanter.net

Your first example worked great for me! That created the certificate for me, and then I was able to import it (cert.pem, chain.pem, and privkey.pem) into the Server app, and now I’m running with https.

Renewing every 90 days may be a pain, as I don’t know of any way to automate importing these files into Server.app, but I’ll cross that bridge when I come to it.

Thank you very much!

Incidentally, there is a feature certbot renew which will try to renew the certificate for you when it's less than 30 days away from expiring (by repeating the authorization process). This is meant to be run at least once per day from cron. If you can make a shell script which can perform the import from the command line, you could then use certbot renew --renew-hook your-import-command, run automatically from cron. The --renew-hook command gets run only when a renewal has actually taken place.

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