The client lacks sufficient authorization - 404

Hi there,

first of all — thanks letsencrypt to try to make the certificate pain a bit more bearable — highly appreciated!

I just tried to get my first certificate with the client on an ubuntu production system (for a test domain however). Therefore I cannot stop the nginx running there to free up the port 80 (or 443 as ssl is already in place with a startssl cert).
So thats why I tried to do it the webroot way (like described here: https://letsencrypt.readthedocs.org/en/latest/using.html#webroot) but always run into an error:

./letsencrypt-auto certonly --webroot -w /var/www/default -d mydomain.net
Updating letsencrypt and virtual environment dependencies.......
Running with virtualenv: /root/.local/share/letsencrypt/bin/letsencrypt certonly --webroot -w /var/www/default -d mydomain.net
Failed authorization procedure. mydomain.net (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://mydomain.net/.well-known/acme-challenge/789[...]eSA [255.255.255.255]: 404

IMPORTANT NOTES:
 - The following 'urn:acme:error:unauthorized' errors were reported by
   the server:

   Domains: mydomain.net
   Error: The client lacks sufficient authorization

So I know there are already quite some topics around the “client lacks auth” error, but none of them covers a 404 being the source for the error. As the client tries to “find” a certain something in the .well-known directory I assume I need to place something there? However, I could not find anything in the documentation explaining what needs to be put there.

So my question would be — what to put there and where to get it from? Or am I completely wrong with using the webroot for my usecase?

Thanks so much!

2 Likes

The problem is related to LE not being able to reach http://mydomain.net/.well-known/acme-challenge/789

I’m assuming that you have used you real domain name and replaced it with “mydomain.net” here.

Can you reach the link in your browser ? or is there a permissions issue preventing this working in your server setup ?

Hi,

I’ve not got LE webroot to work yet. I’m getting the same:

Failed authorization procedure. host.mydomain.co.uk (http-01): unauthorized :: The client lacks sufficient authorization :: Invalid response from http://host.mydomain.co.uk/.well-known/acme-challenge/BVKdxVLUPa2dw98bmqka-mXpQVQioQHy7ima2xP56MY [99.999.99.99]: 404

IMPORTANT NOTES:

  • The following ‘unauthorized’ errors were reported by the server:

Domains: host.mydomain.co.uk
Error: The client lacks sufficient authorization

If I open the above link in the browser I get:

Not Found
The requested URL /.well-known/acme-challenge/p3T0CBKB-wLps9J9FKKLAl1OKuKcgdjtD0WMFZzE_6o was not found on this server.

However, looking in the webroot /.well-known/acme-challenge directory I don’t find any files!

I’m using Jessie and Apache 2.4. Web user/group is www-data:www-data. I’ve checked the directory permissions and tried changing VirtualHost config for / and all seems OK. Even added a specific Directory stanza for .well-known directory, all to no avail.

Any help would be appreciated.

If you add a file such as “aa” in /.well-known/acme-challenge/ can you get to it in your browser ? I just tested ( I was quick before the edit :wink: ) and get a “The requested URL /.well-known/acme-challenge was not found on this server.” for that directory

Hi! I’m facing a similar situation. (disclaimer: really new at this).

What am I supposed to put inside my /.well-known/acme-challenge/ ?

Thanks!

if you are using letsencrypt-auto to do everything, it should put all the files in tehre for you ( although there has been a permissions issue for some recently). If you are working in “–manual” mode then you will be told what file to put into there.

There could be a number of reasons for the same error. The first quick check is that the acme-challenge folder has permissions 755 and, if you place any file in there ( a basic one line text file is fine) you should be able to get to it in the browser

1 Like

Thank you. I was doing quite a lot of things wrong. Now it works perfectly :slight_smile:

1 Like

I get the same result:

The requested URL /.well-known/acme-challenge/aa was not found on this server.

Don’t know what to try next. The problem is maybe to do with permissions in Apache config.

It could be one of a number of things

I’d start by checking if the /.well-known/acme-challenge/ directory exists currently … and that the permissions on both .well-known and acme-challenge are 755. I’d then add a test file ( just a onlne line text should be fine ) and check that you can reach it in your browser. If not, then it is an Apache config issue and needs debugging and correcting first.

OK. Confirmed the .well-known/acme-challenge directories exist and have 755 permisions. I was able to browse to a one line test file as you suggested with no problem. The site is working fine.

A few points:

The (owncloud) site is https self-certified running as virtual host.

nslookup gives correct IPs for IPv4 and IPv6 for the host.

Apache is listening on ipv4 and ipv6. The host I am trying with also has an ipv6 global address.

LE seems to be trying to connect using http which won’t work as there are several other http virtual hosts running on the one ipv4 address and the rdns is for another host.

Here is relevant snippet from latest LE log with domain name / ip masked.

2015-12-05 21:39:32,885:DEBUG:root:Sending GET request to https://acme-v01.api.letsencrypt.org/acme/authz/LqKidpVXdh6fZBzR9pHg_ljv8oVfsDjqrLvT3MYXbXE. args: (), kwargs: {}
2015-12-05 21:39:32,886:INFO:requests.packages.urllib3.connectionpool:Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
2015-12-05 21:39:33,089:DEBUG:requests.packages.urllib3.connectionpool:“GET /acme/authz/LqKidpVXdh6fZBzR9pHg_ljv8oVfsDjqrLvT3MYXbXE HTTP/1.1” 200 1107
2015-12-05 21:39:33,092:DEBUG:root:Received <Response [200]>. Headers: {‘Content-Length’: ‘1107’, ‘Expires’: ‘Sat, 05 Dec 2015 21:39:33 GMT’, ‘Strict-Transport-Security’: ‘max-age=604800’, ‘Server’: ‘nginx’, ‘Connection’: ‘keep-alive’, ‘Link’: ‘https://acme-v01.api.letsencrypt.org/acme/new-cert;rel=“next”’, ‘Pragma’: ‘no-cache’, ‘Cache-Control’: ‘max-age=0, no-cache, no-store’, ‘Date’: ‘Sat, 05 Dec 2015 21:39:33 GMT’, ‘X-Frame-Options’: ‘DENY’, ‘Content-Type’: ‘application/json’, ‘Replay-Nonce’: ‘zoP0AQ6RvFWY0Syef1vKkWP55KNR0Y97HpLsYarS-aU’}. Content: '{“identifier”:{“type”:“dns”,“value”:“host.mydomain.co.uk”},“status”:“invalid”,“expires”:“2015-12-12T21:39:29Z”,“challenges”:[{“type”:“http-01”,“status”:“invalid”,“error”:{“type”:“urn:acme:error:unauthorized”,“detail”:“Invalid response from http://host.mydomain.co.uk/.well-known/acme-challenge/UL-ip1VN2e1G1Y3iDCU9Iw8Hgl2dp-SbPOZExQ6jmrA [99.999.99.99]: 404”},“uri”:“https://acme-v01.api.letsencrypt.org/acme/challenge/LqKidpVXdh6fZBzR9pHg_ljv8oVfsDjqrLvT3MYXbXE/970091",“token”:“UL-ip1VN2e1G1Y3iDCU9Iw8Hgl2dp-SbPOZExQ6jmrA”,“keyAuthorization”:“UL-ip1VN2e1G1Y3iDCU9Iw8Hgl2dp-SbPOZExQ6jmrA.ts4r63kWSQE4E6t9CM8QKq0hKJkcURBJ11uDzBvXK2w”,“validationRecord”:[{“url”:“http://host.mydomain.co.uk/.well-known/acme-challenge/UL-ip1VN2e1G1Y3iDCU9Iw8Hgl2dp-SbPOZExQ6jmrA”,“hostname”:“host.mydomain.co.uk”,“port”:“80”,“addressesResolved”:[99.999.99.99],“addressUsed”:“99.999.99.99”}]},{“type”:“tls-sni-01”,“status”:“pending”,“uri”:“https://acme-v01.api.letsencrypt.org/acme/challenge/LqKidpVXdh6fZBzR9pHg_ljv8oVfsDjqrLvT3MYXbXE/970092”,“token”:“VHC6fO71wdf2X9cArQlFF8GM-vEe5G7mQL2xYG_GVc0”}],"combinations”:[[1],[0]]}'
2015-12-05 21:39:33,092:DEBUG:acme.client:Received response <Response [200]> (headers: {‘Content-Length’: ‘1107’, ‘Expires’: ‘Sat, 05 Dec 2015 21:39:33 GMT’, ‘Strict-Transport-Security’: ‘max-age=604800’, ‘Server’: ‘nginx’, ‘Connection’: ‘keep-alive’, ‘Link’: ‘https://acme-v01.api.letsencrypt.org/acme/new-cert;rel=“next”’, ‘Pragma’: ‘no-cache’, ‘Cache-Control’: ‘max-age=0, no-cache, no-store’, ‘Date’: ‘Sat, 05 Dec 2015 21:39:33 GMT’, ‘X-Frame-Options’: ‘DENY’, ‘Content-Type’: ‘application/json’, ‘Replay-Nonce’: ‘zoP0AQ6RvFWY0Syef1vKkWP55KNR0Y97HpLsYarS-aU’}): '{“identifier”:{“type”:“dns”,“value”:“host.mydomain.co.uk”},“status”:“invalid”,“expires”:“2015-12-12T21:39:29Z”,“challenges”:[{“type”:“http-01”,“status”:“invalid”,“error”:{“type”:“urn:acme:error:unauthorized”,“detail”:“Invalid response from http://host.mydomain.co.uk/.well-known/acme-challenge/UL-ip1VN2e1G1Y3iDCU9Iw8Hgl2dp-SbPOZExQ6jmrA [99.999.99.99]: 404”},“uri”:“https://acme-v01.api.letsencrypt.org/acme/challenge/LqKidpVXdh6fZBzR9pHg_ljv8oVfsDjqrLvT3MYXbXE/970091",“token”:“UL-ip1VN2e1G1Y3iDCU9Iw8Hgl2dp-SbPOZExQ6jmrA”,“keyAuthorization”:“UL-ip1VN2e1G1Y3iDCU9Iw8Hgl2dp-SbPOZExQ6jmrA.ts4r63kWSQE4E6t9CM8QKq0hKJkcURBJ11uDzBvXK2w”,“validationRecord”:[{“url”:“http://host.mydomain.co.uk/.well-known/acme-challenge/UL-ip1VN2e1G1Y3iDCU9Iw8Hgl2dp-SbPOZExQ6jmrA”,“hostname”:“host.mydomain.co.uk”,“port”:“80”,“addressesResolved”:[“99.999.99.99”],“addressUsed”:“99.999.99.99”}]},{“type”:“tls-sni-01”,“status”:“pending”,“uri”:“https://acme-v01.api.letsencrypt.org/acme/challenge/LqKidpVXdh6fZBzR9pHg_ljv8oVfsDjqrLvT3MYXbXE/970092”,“token”:“VHC6fO71wdf2X9cArQlFF8GM-vEe5G7mQL2xYG_GVc0”}],"combinations”:[[1],[0]]}'
2015-12-05 21:39:33,094:INFO:letsencrypt.reporter:Reporting to user: The following ‘unauthorized’ errors were reported by the server:

Domains: host.mydomain.co.uk
Error: The client lacks sufficient authorization

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.
2015-12-05 21:39:33,094:INFO:letsencrypt.auth_handler:Cleaning up challenges
2015-12-05 21:39:33,095:DEBUG:letsencrypt.plugins.webroot:Removing /var/www/host.mydomain.co.uk/owncloud/.well-known/acme-challenge/UL-ip1VN2e1G1Y3iDCU9Iw8Hgl2dp-SbPOZExQ6jmrA
2015-12-05 21:39:33,097:DEBUG:letsencrypt.cli:Exiting abnormally:
Traceback (most recent call last):
File “./letsencrypt”, line 11, in
sys.exit(main())
File “/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/cli.py”, line 1140, in main
return args.func(args, config, plugins)
File “/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/cli.py”, line 490, in obtaincert
_auth_from_domains(le_client, config, domains, plugins)
File “/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/cli.py”, line 328, in _auth_from_domains
lineage = le_client.obtain_and_enroll_certificate(domains, plugins)
File “/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/client.py”, line 229, in obtain_and_enroll_certificate
certr, chain, key, _ = self.obtain_certificate(domains)
File “/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/client.py”, line 212, in obtain_certificate
return self._obtain_certificate(domains, csr) + (key, csr)
File “/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/client.py”, line 170, in _obtain_certificate
authzr = self.auth_handler.get_authorizations(domains)
File “/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/auth_handler.py”, line 84, in get_authorizations
self._respond(cont_resp, dv_resp, best_effort)
File “/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/auth_handler.py”, line 142, in _respond
self._poll_challenges(chall_update, best_effort)
File “/root/.local/share/letsencrypt/local/lib/python2.7/site-packages/letsencrypt/auth_handler.py”, line 204, in _poll_challenges
raise errors.FailedChallenges(all_failed_achalls)
FailedChallenges: Failed authorization procedure. host.mydomain.co.uk (http-01): unauthorized :: The client lacks sufficient authorization :: Invalid response from http://host.mydomain.co.uk/.well-known/acme-challenge/UL-ip1VN2e1G1Y3iDCU9Iw8Hgl2dp-SbPOZExQ6jmrA [99.999.99.99]: 404

Yes, LE connects via http to confirm the site. You will have to use the “manual” option rather than auto if you can’t set it up to see http because of the other hosts.

Thank you. I didn’t understand that http was needed and I must have missed that in the documentation.

Good morning,

thanks serverco for getting back to me. Here are my answers to your initial questions:

Yes — I just masked the real domain for posting here and replaced it with mydomain.net

No I cannot reach the link in the browser. If I am not misinterpreting the error message I have posted it throws a 404 not found error. I have manually created the /.well-known/acme-challenge folder in the nginx docroot and it turned out my nginx conf was blocking requests that start with a dot (to prevent access to .ht[access|passwd] files...
Now it is just working as expected. Thanks.

There's one last question: How can I generate a certificate that includes both the mydomain.net and www.mydomain.net — if even possible.

Thanks so much again for putting all this effort into a better and easier encryption!

Add all the domains you want for that certificate on the command line;

./letsencrypt-auto certonly --webroot -w /var/www/default -d mydomain.net -d www.mydomain.net

Hello,
Thanks for this great project!

As mmaedler, I get the same 404 message but the solution given here doesn’t work for me.

My server “MyServer” is accessible from the Internet (http, port 80) and a manual test page I put into ~.well-known/acme-challenge is also visible.

But when I try to get a cert using the command “./letsencrypt-auto certonly --manual -w /var/www/html -d MyServer” (I tried --manual and --webroot with no more success), I get those messages :
Failed authorization procedure. MyServer (http-01): urn:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from http://MyServer/.well-known/acme-challenge/-cpx90pHqUIY7sRCVZ6Hqdtku9V3KmvY9ld3HnaTcSQ [5.56.47.138]: 404

IMPORTANT NOTES:

  • The following ‘urn:acme:error:unauthorized’ errors were reported by
    the server:

    Domains: MyServer
    Error: The client lacks sufficient authorization

Here are my httpd’s logs:
error.log:
192.168.255.149 - - [17/Dec/2015:17:54:36 +0100] “GET /favicon.ico HTTP/1.1” 200 1232 “http://MyServer/.well-known/acme-challenge/toto” "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"
192.168.255.175 - - [17/Dec/2015:17:54:52 +0100] “GET / HTTP/1.1” 200 16852 “-” "check_http/v1.4.16 (nagios-plugins 1.4.16)"
access.log:
[Thu Dec 17 17:56:02 2015] [error] [client 192.168.255.149] File does not exist: /home/www/amicare/.well-known/acme-challenge/-cpx90pHqUIY7sRCVZ6Hqdtku9V3KmvY9ld3HnaTcSQ

MyServer is in Redhat Linux Enterprise 6.3 version, so the packages are not sufficient (version of python, …).
So I generate the cert on a Redhat Linux Entreprise 7.2.

I don’t really know where to search now.
Do you have an idea of what I missed?

Thanks a lot again

You get an error that
/home/www/amicare/.well-known/acme-challenge/-cpx90pHqUIY7sRCVZ6Hqdtku9V3KmvY9ld3HnaTcSQ
does not exist.

With your apache ( I assume) config, is that the location it should be in for

http://MyServer/.well-known/acme-challenge/-cpx90pHqUIY7sRCVZ6Hqdtku9V3KmvY9ld3HnaTcSQ ?

You say the manual test page in .well-known/acme-challenge/ was visible … was that the internal ?

do you have any redirects (.htaccess ) that could be affecting it ?

Hi!,
Thanks for your response.

Yes, this URL is the one where it should be.
My project is under “/home/www/amicare” and DocumentRoot has been defined as “/home/www/amicare” in my /etc/httpd/conf/httpd.conf
I’ve got a .htaccess where I defined: Options +FollowSymlinks +Indexes.
And I made a "chmod -R 777 /home/www/amicare/.well-known"
When I am surfing from Internet to http://MyServer/.well-known/acme-challenge, I get:
Index of /.well-known/acme-challenge

Name	Last modified	Size	Description

Parent Directory -
Apache/2.2.15 (Red Hat) Server at MyServer Port 80

But I can’t get a cert from LE.

Thanks for your help

Hello @aegle,

Please, perform the following actions:

1.- Create a dummy file in acme-challenge dir in your Red Hat 6.3 Server.
printf "%s" thisisthecontentoffile > /home/www/amicare/.well-known/acme-challenge/dummychallengefile

2.- Launch below command from your Red Hat 7.2 and from internet and show us the complete output (change yourdomain.tld for your actual domain):
curl -i http://yourdomain.tld/.well-known/acme-challenge/dummychallengefile | cat -A

With this data we should check whether there is any issue with your apache conf, dns, etc. (keep in mind that should be better if you could show your real domain).

Cheers,
sahsanu

Hello sahsanu,

Thanks for your reply.
Here is the result of the command launched from my RH7.2 server.
I put one my really testing server / domain as asked.

[root@integ4 letsencrypt]# curl -i http://integ-amicare.aegle.fr/.well-known/acme-challenge/dummychallengefile | cat -A
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 22 100 22 0 0 678 0 --:–:-- --:–:-- --:–:-- 709
HTTP/1.1 200 OK^M$
Date: Mon, 21 Dec 2015 10:08:01 GMT^M$
Server: Apache/2.2.15 (Red Hat)^M$
Last-Modified: Mon, 21 Dec 2015 10:07:26 GMT^M$
ETag: “203d5f-16-52765a7f83b7f”^M$
Accept-Ranges: bytes^M$
Content-Length: 22^M$
Content-Type: text/plain; charset=UTF-8^M$
Connection: close^M$
^M$
thisisthecontentoffile[root@integ4 letsencrypt]#

From another server on Internet, I get same successful response.

Regards.

Hello @aegle,

The output seems correct to me, the only that could cause your problems is the Content-Type, seems letsencrypt doesn't like it if the charset is added.

As you are using Apache, put a .htaccess file inside .well-known dir with this content:

ForceType 'text/plain'
AddDefaultCharset Off

And try again the test using curl, in Content-type you should only see:

Content-Type: text/plain

If the test is ok, try letsencrypt again but using --staging flag to create a non valid certificate, once you get the certificate created you can remove --staging from your command and this time it will create a valid certificate. I'm saying to use staging just in case you hit the rate limit.

Note: Keep in mind that you should only use -d integ-amicare.aegle.fr I'm saying it because www.integ-amicare.aegle.fr is not resolving by DNS so you can't validate it.

Cheers,
sahsanu