Let's Encrypt issue - Error 400

I am using the HestiaCP application (version 1.10.4) on a VPS running Ubuntu 24.04. For a few days, I have been trying to resolve an SSL certificate issuance error via Let’s Encrypt, which returns the following message: Error: Let’s Encrypt validation status 400 (lwinfo.com.br). Details: 403:“177.86.106.251: Invalid response from http://lwinfo.com.br/.well-known/acme-challenge/aXs7J5EFyz17L93YeQFqM-3hnwko1uunnN-s5OKYQB4: 404” Below is the error log generated by the HestiaCP system. Error log file:

=============================
Date Time: 2026-09-06 11:37:42
WEB_SYSTEM: apache2
PROXY_SYSTEM: nginx
user: lwinfo
domain: lwinfo.com.br

  • aliases: www.lwinfo.com.br
  • proto: http-01
  • wildcard:

==[Step 1]==

  • status: 200
  • nonce: ak_Pb0o-w-FQFoVFpwh5BFDUCO5Zh_vo9EvCEMts6cXYkhga7mo
  • answer: HTTP/2 200
    server: nginx
    date: Sun, 06 Sep 2026 14:37:42 GMT
    content-type: application/json
    content-length: 961
    cache-control: public, max-age=0, no-cache
    replay-nonce: ak_Pb0o-w-FQFoVFpwh5BFDUCO5Zh_vo9EvCEMts6cXYkhga7mo
    x-frame-options: DENY
    strict-transport-security: max-age=604800

==[API call]==
exit status: 0

==[Step 2]==

https://acme-v02.api.letsencrypt.org/acme/authz/3697777155/774518846066

- finalize: https://acme-v02.api.letsencrypt.org/acme/finalize/3697777155/554052004336

  • payload: {“identifiers”:[{“type”:“dns”,“value”:“lwinfo.com.br”},{“type”:“dns”,“value”:“www.lwinfo.com.br”}]}
  • answer: HTTP/2 201
    server: nginx
    date: Sun, 06 Sep 2026 14:37:43 GMT
    content-type: application/json
    content-length: 495
    boulder-requester: 3697777155
    cache-control: public, max-age=0, no-cache
    link: https://acme-v02.api.letsencrypt.org/directory;rel=“index”
    location: https://acme-v02.api.letsencrypt.org/acme/order/3697777155/554052004336
    replay-nonce: ak_Pb0o-eTH3PrIGl3urX1TQtj4mZseXyDTwW_32NX-EssvGFn4
    x-frame-options: DENY
    strict-transport-security: max-age=604800

{
“status”: “pending”,
“expires”: “2026-09-13T14:37:43Z”,
“identifiers”: [
{
“type”: “dns”,
“value”: “lwinfo.com.br”
},
{
“type”: “dns”,
“value”: “www.lwinfo.com.br”
}
],
“authorizations”: [
“https://acme-v02.api.letsencrypt.org/acme/authz/3697777155/774518846056”,
“https://acme-v02.api.letsencrypt.org/acme/authz/3697777155/774518846066”
],
“finalize”: “https://acme-v02.api.letsencrypt.org/acme/finalize/3697777155/554052004336”
}
order: https://acme-v02.api.letsencrypt.org/acme/order/3697777155/554052004336

==[API call]==
exit status: 0

==[Step 3]==

{
“identifier”: {
“type”: “dns”,
“value”: “lwinfo.com.br”
},
“status”: “pending”,
“expires”: “2026-09-13T14:37:43Z”,
“challenges”: [
{
“type”: “tls-alpn-01”,
“url”: “https://acme-v02.api.letsencrypt.org/acme/chall/3697777155/774518846056/hQe3iA”,
“status”: “pending”,
“token”: “aXs7J5EFyz17L93YeQFqM-3hnwko1uunnN-s5OKYQB4”
},
{
“type”: “http-01”,
“url”: “https://acme-v02.api.letsencrypt.org/acme/chall/3697777155/774518846056/kyZe9w”,
“status”: “pending”,
“token”: “aXs7J5EFyz17L93YeQFqM-3hnwko1uunnN-s5OKYQB4”
},
{
“type”: “dns-01”,
“url”: “https://acme-v02.api.letsencrypt.org/acme/chall/3697777155/774518846056/5nohog”,
“status”: “pending”,
“token”: “aXs7J5EFyz17L93YeQFqM-3hnwko1uunnN-s5OKYQB4”
}
]
}

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[API call]==
exit status: 0

==[Step 5]==

{
“type”: “urn:ietf:params:acme:error:malformed”,
“detail”: “Unable to update challenge :: authorization must be pending”,
“status”: 400
}

==[Debug information Step 5]==
{
“type”: “http-01”,
“url”: “https://acme-v02.api.letsencrypt.org/acme/chall/3697777155/774518846056/kyZe9w”,
“status”: “invalid”,
“validated”: “2026-09-06T14:37:50Z”,
“error”: {
“type”: “urn:ietf:params:acme:error:unauthorized”,
“detail”: “177.86.106.251: Invalid response from http://lwinfo.com.br/.well-known/acme-challenge/aXs7J5EFyz17L93YeQFqM-3hnwko1uunnN-s5OKYQB4: 404”,
“status”: 403
},
“token”: “aXs7J5EFyz17L93YeQFqM-3hnwko1uunnN-s5OKYQB4”,
“validationRecord”: [
{
“url”: “http://lwinfo.com.br/.well-known/acme-challenge/aXs7J5EFyz17L93YeQFqM-3hnwko1uunnN-s5OKYQB4”,
“hostname”: “lwinfo.com.br”,
“port”: “80”,
“addressesResolved”: [
“177.86.106.251”
],
“addressUsed”: “177.86.106.251”
}
]
}

==[Abort Step 5]==
=> Wrong status

I have already read and followed several “step-by-step” guides that were supposed to solve the problem, but unfortunately, I haven’t had any success. I am seeking help because I am feeling discouraged and frustrated by this issue…

Thank you in advance for your attention.

Another relevant observation is that the subdomain I used to access the panel successfully issued the SSL certificate via Let’s Encrypt, although this was done using the command line. I have also gone through and checked all the posts prior to mine that are related in some way to my issue. Another equally relevant piece of information is that I do not have IPv6 configured on my VPS; port 80 is listening, and Let’s Debug is returning “OK.”

Please, show your nginx conf:

cat /etc/nginx/conf.d/domains/lwinfo.com.br.conf
cat /etc/nginx/conf.d/domains/lwinfo.com.br.conf
#=========================================================================#
# Default Web Domain Template                                             #
# DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
# https://hestiacp.com/docs/server-administration/web-templates.html      #
#=========================================================================#

server {
        listen      172.16.138.46:80;
        server_name lwinfo.com.br www.lwinfo.com.br;
        error_log   /var/log/apache2/domains/lwinfo.com.br.error.log error;

        include /home/lwinfo/conf/web/lwinfo.com.br/nginx.forcessl.conf*;

        location ~ /\.(?!well-known\/|file) {
                deny all;
                return 404;
        }

        location / {
                proxy_pass http://172.16.138.46:8080;

                location ~* ^.+\.(css|htm|html|js|mjs|json|xml|apng|avif|bmp|cur|gif|ico|jfif|jpg|jpeg|pjp|pjpeg|png|svg|tif|tiff|webp|aac|caf|flac|m4a|midi|mp3|ogg|opus|wav|3gp|av1|avi|m4v|mkv|mov|mpg|mpeg|mp4|mp4v|webm|otf|ttf|woff|woff2|doc|docx|odf|odp|ods|odt|pdf|ppt|pptx|rtf|txt|xls|xlsx|7z|bz2|gz|rar|tar|tgz|zip|apk|appx|bin|dmg|exe|img|iso|jar|msi|webmanifest)$ {
                        try_files  $uri @fallback;

                        root       /home/lwinfo/web/lwinfo.com.br/public_html;
                        access_log /var/log/apache2/domains/lwinfo.com.br.log combined;
                        access_log /var/log/apache2/domains/lwinfo.com.br.bytes bytes;

                        expires    max;
                }
        }

        location @fallback {
                proxy_pass http://172.16.138.46:8080;
        }

        location /error/ {
                alias /home/lwinfo/web/lwinfo.com.br/document_errors/;
        }

        include /home/lwinfo/conf/web/lwinfo.com.br/nginx.conf_*;
}

Edit the file and move this line:

        include /home/lwinfo/conf/web/lwinfo.com.br/nginx.conf_*;

Before this one:

        include /home/lwinfo/conf/web/lwinfo.com.br/nginx.forcessl.conf*;

Save the file, restart nginx and check whether you see the challenge instead of the 404 error when browsing http://lwinfo.com.br/.well-known/acme-challenge/test

Please show again the conf and the other two commands:

cat /etc/nginx/conf.d/domains/lwinfo.com.br.conf
ls -la /home/lwinfo/conf/web/lwinfo.com.br/
date && systemctl status nginx --no-pager -l
#=========================================================================#
# Default Web Domain Template                                             #
# DO NOT MODIFY THIS FILE! CHANGES WILL BE LOST WHEN REBUILDING DOMAINS   #
# https://hestiacp.com/docs/server-administration/web-templates.html      #
#=========================================================================#

server {
        listen      172.16.138.46:80;
        server_name lwinfo.com.br www.lwinfo.com.br;
        error_log   /var/log/apache2/domains/lwinfo.com.br.error.log error;

        include /home/lwinfo/conf/web/lwinfo.com.br/nginx.conf_*;
        include /home/lwinfo/conf/web/lwinfo.com.br/nginx.forcessl.conf*;

        location ~ /\.(?!well-known\/|file) {
                deny all;
                return 404;
        }

        location / {
                proxy_pass http://172.16.138.46:8080;

                location ~* ^.+\.(css|htm|html|js|mjs|json|xml|apng|avif|bmp|cur|gif|ico|jfif|jpg|jpeg|pjp|pjpeg|png|svg|tif|tiff|webp|aac|caf|flac|m4a|midi|mp3|ogg|opus|wav|3gp|av1|avi|m4v|mkv|mov|mpg|mpeg|mp4|mp4v|webm|otf|ttf|woff|woff2|doc|docx|odf|odp|ods|odt|pdf|ppt|pptx|rtf|txt|xls|xlsx|7z|bz2|gz|rar|tar|tgz|zip|apk|appx|bin|dmg|exe|img|iso|jar|msi|webmanifest)$ {
                        try_files  $uri @fallback;

                        root       /home/lwinfo/web/lwinfo.com.br/public_html;
                        access_log /var/log/apache2/domains/lwinfo.com.br.log combined;
                        access_log /var/log/apache2/domains/lwinfo.com.br.bytes bytes;

                        expires    max;
                }
        }

        location @fallback {
                proxy_pass http://172.16.138.46:8080;
        }

        location /error/ {
                alias /home/lwinfo/web/lwinfo.com.br/document_errors/;
        }

}
total 20
drwxr-xr-x 2 root root   4096 Sep  6 16:51 .
drwxr-x--x 4 root root   4096 Sep  6 16:34 ..
-rw-r----- 1 root lwinfo 1629 Sep  6 16:34 apache2.conf
-rw-r----- 1 root lwinfo 1554 Sep  6 18:15 nginx.conf
-rw-r--r-- 1 root root    147 Sep  6 16:52 nginx.conf_letsencrypt
lrwxrwxrwx 1 root root     58 Sep  6 16:51 nginx.ssl.conf_letsencrypt -> /home/lwinfo/conf/web/lwinfo.com.br/nginx.conf_letsencrypt
Sun Sep  6 06:30:31 PM -03 2026
● nginx.service - nginx - high performance web server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Sun 2026-09-06 18:16:09 -03; 14min ago
       Docs: https://nginx.org/en/docs/
    Process: 275598 ExecStart=/usr/sbin/nginx -c ${CONFFILE} (code=exited, status=0/SUCCESS)
   Main PID: 275600 (nginx)
      Tasks: 6 (limit: 4590)
     Memory: 6.5M (peak: 7.7M)
        CPU: 169ms
     CGroup: /system.slice/nginx.service
             ├─275600 "nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf"
             ├─275601 "nginx: worker process"
             ├─275602 "nginx: worker process"
             ├─275603 "nginx: worker process"
             ├─275605 "nginx: worker process"
             └─275606 "nginx: cache manager process"

Sep 06 18:16:09 server.lwinfo.com.br systemd[1]: Starting nginx.service - nginx - high performance web server...
Sep 06 18:16:09 server.lwinfo.com.br systemd[1]: Started nginx.service - nginx - high performance web server.

That’s strange, all looks fine…

Show the output of these commands:

ss -tlnp | grep ':80 '
ip a
v-list-sys-ips json
LISTEN 0      511                       172.16.138.46:80         0.0.0.0:*    users:(("nginx",pid=275605,fd=12),("nginx",pid=275603,fd=12),("nginx",pid=275602,fd=12),("nginx",pid=275601,fd=12),("nginx",pid=275600,fd=12))
LISTEN 0      511                      177.86.106.251:80         0.0.0.0:*    users:(("nginx",pid=275605,fd=13),("nginx",pid=275603,fd=13),("nginx",pid=275602,fd=13),("nginx",pid=275601,fd=13),("nginx",pid=275600,fd=13))
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: enX0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 66:b6:11:2a:e9:2c brd ff:ff:ff:ff:ff:ff
    inet 172.16.138.46/30 brd 172.16.138.47 scope global enX0
       valid_lft forever preferred_lft forever
    inet 177.86.106.251/32 scope global enX0
       valid_lft forever preferred_lft forever
    inet6 fe80::64b6:11ff:fe2a:e92c/64 scope link 
       valid_lft forever preferred_lft forever
{
    "172.16.138.46": {
        "OWNER": "lwinfo",
        "STATUS": "shared",
        "NAME": "",
        "U_SYS_USERS": "lwinfo",
        "U_WEB_DOMAINS": "2",
        "INTERFACE": "enX0",
        "NETMASK": "255.255.255.252",
        "NAT": "177.86.106.251",
        "TIME": "23:10:48",
        "DATE": "2026-09-01"
        },
    "177.86.106.251": {
        "OWNER": "lwinfo",
        "STATUS": "shared",
        "NAME": "",
        "U_SYS_USERS": "",
        "U_WEB_DOMAINS": "0",
        "INTERFACE": "enX0",
        "NETMASK": "255.255.255.255",
        "NAT": "",
        "TIME": "23:10:52",
        "DATE": "2026-09-01"
        }
}

The problem is that your web domain is not using the public ip but the private ip. You need to edit the web domain settings in Hestia and configure it to use 177.86.106.251 instead of 172.16.138.46.

Understood, but how do I get to that option? I don’t recall configuring the IP address at any point during the installation process. Could you please explain where I can change that information in the panel?

One more thing: did you notice I mentioned that I managed to issue a valid certificate for the subdomain server.lwinfo.com.br via the command line?

waterfox_B0LzrEKWcl

Click on your web domain or the pencil icon.

Then you can select the correct ip and save:

I suppose that domain is using the right IP in nginx conf.

The IP currently configured is 177.86.106.251.

No, you must use the external IP. The issue here is that you may be seeing two identical IPs, but one is actually your private IP being exposed through the NAT IP, while the other is the actual external IP.

So, as you can see in the image from the previous reply, the external IP address is the one that is configured. From the little I’ve been able to gather about the error, something is preventing the server from generating the “well-known” page. I’m not certain about this, but that is my strong impression.

Even so, the problem remains unresolved… Thank you very much for helping me solve this issue.

Click on the IP and you should see two IPs, and the two should be the same 177.86.106.251 but one is actually the internal IP, you must select the other one.

Here is a screenshot taken after the recommended interactions.

I want to cry. :laughing:

Check that you are selecting the right IP checking the conf:

grep listen /etc/nginx/conf.d/domains/lwinfo.com.br.conf
listen      177.86.106.251:80