Incorrect validation certificate for tls-sni-01 challenge. Received 2 certificate(s)

# ./certbot-auto --nginx

Obtaining a new certificate
/root/.local/share/letsencrypt/lib/python2.6/site-packages/acme/jose/ DeprecationWarning: signer and verifier have been deprecated. Please use sign and verify instead.
  signer = key.signer(self.padding, self.hash)
Performing the following challenges:
tls-sni-01 challenge for
Waiting for verification...
Cleaning up challenges
Failed authorization procedure. (tls-sni-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Incorrect validation certificate for tls-sni-01 challenge. Requested ad86d183a42a7553a92825b8a3513582.f5c65beec2c3b4e92dc29504f68889e0.acme.invalid from Received 2 certificate(s), first certificate had names ",,"

 - The following errors were reported by the server:

   Type:   unauthorized
   Detail: Incorrect validation certificate for tls-sni-01 challenge.
   from Received 2 certificate(s), first
   certificate had names ",,"

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address.
  • operating system Ubuntu Lucid (10.04)
# cat /proc/version
Linux version 4.9.15-x86_64-linode81 (maker@build) (gcc version 4.7.2 (Debian 4.7.2-5) ) #1 SMP Fri Mar 17 09:47:36 EDT 2017
  • web server Nginx 1.0.6
# ./sbin/nginx -V
nginx: nginx version: nginx/1.0.6
nginx: built by gcc 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
nginx: TLS SNI support enabled
nginx: configure arguments: --prefix=/opt/nginx --user=nginx --group=nginx --with-http_ssl_module

I reviewed a few similar threads that already existed on this forum, but none seemed to help.

The server is normally behind CloudFlare, but I turned CF off (direct access) for the purpose of installing Let’s Encrypt. There is one certificate active for, from StartSSL (StartCom) which I’d like to replace by Let’s Encrypt.

The problem seems to be with the /.well-known/acme-challenge folder access.
Please place a test.txt file at http(s)://

@rg305 No, he’s using the nginx plugin, which uses tls-sni-01, not http-01. It’s not looking for a challenge file, but rather trying to use SNI to present a challenge certificate. In this case that would probably be the best option, but isn’t why it’s failing at present.

@piskvorky I’m not familiar enough with Cloudflare’s options for TLS termination to know for sure whether or not it still terminates even if you’re connecting directly. I suspect that’s the case here. You might attempt using webroot authentication (http-01, what rg305 was referring to above), as this will work even with Cloudflare enabled so you won’t need to disable it every time you need to renew.

I would recommend using the nginx plugin for installing (as this installs the certificate and reloads the webserver automatically), but webroot for challenge. This can be done with the flags -i nginx -a webroot.

1 Like

Thanks @jared.m, @rg305 . While I read up on the webroot documentation, would you mind explaining what that error means? Why are the 2 certificate(s) a problem, what exactly is invalid, what’s the problem?


This is described a bit at

The TLS-SNI-01 authentication method (which is used by the nginx plugin and not by the webroot plugin) makes a TLS connection on port 443 of your server and expects to find a custom self-signed certificate under a particular name. Some Certbot plugins that support this method attempt to satisfy this challenge by temporarily reconfiguring your web server to know about this custom certificate. However, if this process fails (because the Certbot plugin didn’t understand how to reconfigure your local web server, because the server it reconfigured wasn’t actually the one that was listening on port 443 on your server, or because whatever listens on port 443 for your domain name is not actually the same device that you’re running Certbot on, among other reasons), the certificate authority may complain that when it attempted to connect, it was given a different certificate by your web server, other than the custom self-signed one that it expected.

OK, thanks, I read through the docs and I think I got it.

Is there any downside to installing multiple certificates, one for each domain, for a single machine/web server? (versus a single certificate for multiple (sub)domains). What’s the best practice?

I’m asking because there are several sites running under that same nginx and IP, so I’d like to minimize certificate maintenance / renewal / whatever issues in the future.

It’s a trade off. Using a single certificate which covers all the names means very old software incapable of SNI (Server Name Indication) will still be able to connect successfully even though all the servers share the same IP address. On the other hand using separate certs avoids visitors who are inquisitive being confused if the names inside are unexpected, or making a connection between sites you didn’t intend. It also makes life easier if some but not all the services move to a different machine.

For most people it’s not terribly important which you choose.

1 Like

For posterity, this is the command I used and it seemed to work:

./certbot-auto -i nginx --nginx-server-root /opt/nginx/conf -a webroot --webroot-path /opt/nginx/html/

I also had to symlink /opt/nginx to /etc/nginx first, because otherwise the installation was complaining about missing files in /etc/nginx (despite the explicit --nginx-server-root). I ascribe that to my non-standard nginx location.

Question: what should I put into cron for renewal? Is this the right command?

12 3 * * * /opt/nginx/certbot-auto renew -i nginx --nginx-server-root /opt/nginx/conf -a webroot --webroot-path /opt/nginx/html/ --no-self-upgrade --post-hook "systemctl reload nginx"

Certbot remembers the renewal parameters that you specified, and so you should just use /opt/nginx/certbot-auto renew (optionally with the --no-self-upgrade and the --post-hook, which would probably be better as a --deploy-hook).

1 Like

@SwartzCr, would you be willing to look into whether this is a bug in the implementation of --nginx-server-root? It makes it seems like that option fails to actually change the server root.

Thanks for the deploy-hook tip.

I’m still a little unclear about the relationship between a domain and certbot-auto renew. What happens once I have multiple domains and certificates on this server? How do I renew them from cron?

Do I run certbot-auto renew once and expect it to automagically pick up the right parameters for all domains? Or do I run it multiple times, specifying a different domain each time?

Yes, just once, and it should pick up all of the parameters and attempt all of the necessary renewals. The renewal parameters are stored in files in /etc/letsencrypt/renewal, and certbot-auto renew does a loop over all of the files there, looking at each certificate referred to and performing a separate renewal action for each one using its individual parameters.

1 Like

Excellent! What a pleasant, well-thought out piece of software :slight_smile:

For the posterity again (including my future self):

# adding multiple domains, with a different root for staging
./certbot-auto -i nginx --nginx-server-root /etc/nginx/conf -a webroot --webroot-path /opt/nginx/rare_live --domains,, --webroot-path /opt/nginx/rare_test --domains

# crontab entry; renews ALL domains, as per /etc/letsencrypt/renewal
12 3 * * * /etc/nginx/certbot-auto renew --no-self-upgrade --deploy-hook "/etc/init.d/nginx restart"
1 Like

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