# Certbot Nginx: Server is speaking HTTP/2 over HTTP

**URL:** <https://community.letsencrypt.org/t/certbot-nginx-server-is-speaking-http-2-over-http/201294>\
**Category:** Help\
**Created:** [July 5, 2023, 11:39am UTC](https://community.letsencrypt.org/t/certbot-nginx-server-is-speaking-http-2-over-http/201294 "2023-07-05T11:39:12Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![samyan](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/samyan/32/71762_2.png) [@samyan](https://community.letsencrypt.org/u/samyan)\
**Post date:** [July 5, 2023, 11:39am UTC](https://community.letsencrypt.org/t/certbot-nginx-server-is-speaking-http-2-over-http/201294/1 "2023-07-05T11:39:12Z")

</div>

Hello. I'm trying to generate certs for my sub domain but for some reason it is failing. My OS is Debian 11.

**Default nginx conf:**

```bash
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name _default;

        return 301 http://$host$request_uri; #renamed from https://$host$request_uri;
}

```

**Subdomain nginx conf:**

```bash
server {
        listen 80;
        listen [::]:80;
# listen 443 ssl http2;

        server_name test.legranpay.io;

        access_log /var/log/nginx/app.access.log;
        error_log /var/log/nginx/app.error.log;

        charset utf-8;

        root /var/www/frontend;
        index index.html;

        include snippets/gzip.conf;

        location / {
                try_files $uri $uri/ /index.php?$args;
        }

        location ~ \.php$ {
                try_files $uri /index.php =404;

                fastcgi_split_path_info ^(.+\.php)(/.+)\$;
                fastcgi_pass unix:/run/php/php8.0-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param SCRIPT_NAME $fastcgi_script_name;
        }

        location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|svg|woff|woff2|ttf)\$ {
                expires 1M;
                access_log off;
                add_header Cache-Control "public";
        }

        location ~* \.(?:css|js)\$ {
                expires 7d;
                access_log off;
                add_header Cache-Control "public";
        }

        location ^~ /\.well-known {
                allow all;
        }

        location ~ /\.ht {
                deny all;
        }
}

```

**Result of certbot:**

```bash
Certbot failed to authenticate some domains (authenticator: nginx). The Certificate Authority reported these problems:
  Domain: test.legranpay.io
  Type: connection
  Detail: X.X.X.X: Fetching http://test.legranpay.io/.well-known/acme-challenge/MYOg-pk6F9XdoM-3fTcPBJ3Ma0bYvHh0AQpL6OLb7M8: Server is speaking HTTP/2 over HTTP

Hint: The Certificate Authority failed to verify the temporary nginx configuration changes made by Certbot. Ensure the listed domains point to this nginx server and that it is accessible from the internet.

Some challenges have failed.
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.

```

Nothing special in **/var/log/letsencrypt/letsencrypt.log**

```plaintext
2023-07-05 11:34:22,260:DEBUG:acme.client:Storing nonce: 88B80sdLHPksueNdXpLyTLO6hNpJlZkusA3AvDYXs7RE7cU
2023-07-05 11:34:22,260:INFO:certbot._internal.auth_handler:Challenge failed for domain test.legranpay.io
2023-07-05 11:34:22,260:INFO:certbot._internal.auth_handler:http-01 challenge for test.legranpay.io
2023-07-05 11:34:22,261:DEBUG:certbot._internal.display.obj:Notifying user:
Certbot failed to authenticate some domains (authenticator: nginx). The Certificate Authority reported these problems:
  Domain: test.legranpay.io
  Type: connection
  Detail: X.X.X.X: Fetching http://test.legranpay.io/.well-known/acme-challenge/MYOg-pk6F9XdoM-3fTcPBJ3Ma0bYvHh0AQpL6OLb7M8: Server is speaking HTTP/2 over HTTP

Hint: The Certificate Authority failed to verify the temporary nginx configuration changes made by Certbot. Ensure the listed domains point to this nginx server and that it is accessible from the interne>

2023-07-05 11:34:22,261:DEBUG:certbot._internal.error_handler:Encountered exception:
Traceback (most recent call last):
  File "/snap/certbot/3024/lib/python3.8/site-packages/certbot/_internal/auth_handler.py", line 108, in handle_authorizations
    self._poll_authorizations(authzrs, max_retries, max_time_mins, best_effort)
  File "/snap/certbot/3024/lib/python3.8/site-packages/certbot/_internal/auth_handler.py", line 212, in _poll_authorizations
    raise errors.AuthorizationError('Some challenges have failed.')
certbot.errors.AuthorizationError: Some challenges have failed.

2023-07-05 11:34:22,262:DEBUG:certbot._internal.error_handler:Calling registered functions
2023-07-05 11:34:22,262:INFO:certbot._internal.auth_handler:Cleaning up challenges
2023-07-05 11:34:23,442:DEBUG:certbot._internal.log:Exiting abnormally:
Traceback (most recent call last):
  File "/snap/certbot/3024/bin/certbot", line 8, in <module>
    sys.exit(main())
  File "/snap/certbot/3024/lib/python3.8/site-packages/certbot/main.py", line 19, in main
    return internal_main.main(cli_args)
  File "/snap/certbot/3024/lib/python3.8/site-packages/certbot/_internal/main.py", line 1864, in main
    return config.func(config, plugins)
  File "/snap/certbot/3024/lib/python3.8/site-packages/certbot/_internal/main.py", line 1597, in certonly
    lineage = _get_and_save_cert(le_client, config, domains, certname, lineage)
  File "/snap/certbot/3024/lib/python3.8/site-packages/certbot/_internal/main.py", line 141, in _get_and_save_cert
    lineage = le_client.obtain_and_enroll_certificate(domains, certname)
  File "/snap/certbot/3024/lib/python3.8/site-packages/certbot/_internal/client.py", line 517, in obtain_and_enroll_certificate
    cert, chain, key, _ = self.obtain_certificate(domains)
  File "/snap/certbot/3024/lib/python3.8/site-packages/certbot/_internal/client.py", line 428, in obtain_certificate
    orderr = self._get_order_and_authorizations(csr.data, self.config.allow_subset_of_names)
  File "/snap/certbot/3024/lib/python3.8/site-packages/certbot/_internal/client.py", line 496, in _get_order_and_authorizations
    authzr = self.auth_handler.handle_authorizations(orderr, self.config, best_effort)
  File "/snap/certbot/3024/lib/python3.8/site-packages/certbot/_internal/auth_handler.py", line 108, in handle_authorizations
    self._poll_authorizations(authzrs, max_retries, max_time_mins, best_effort)
  File "/snap/certbot/3024/lib/python3.8/site-packages/certbot/_internal/auth_handler.py", line 212, in _poll_authorizations
    raise errors.AuthorizationError('Some challenges have failed.')
certbot.errors.AuthorizationError: Some challenges have failed.
2023-07-05 11:34:23,444:ERROR:certbot._internal.log:Some challenges have failed.

```

Any idea please?

---

<div class="post-metadata">

**Author:** ![\_az](https://avatars.discourse-cdn.com/v4/letter/_/22d042/32.png) [@\_az](https://community.letsencrypt.org/u/_az)\
**Post date:** [July 5, 2023, 12:03pm UTC](https://community.letsencrypt.org/t/certbot-nginx-server-is-speaking-http-2-over-http/201294/2 "2023-07-05T12:03:23Z")

</div>

Well:

```
$ curl --http2-prior-knowledge -i http://test.legranpay.io
HTTP/2 200
date: Wed, 05 Jul 2023 12:02:21 GMT
content-type: text/html; charset=utf-8
content-length: 57
last-modified: Tue, 04 Jul 2023 14:38:51 GMT
vary: Accept-Encoding
etag: "64a42efb-39"
x-frame-options: SAMEORIGIN
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
accept-ranges: bytes

<html>

<body>
<span>hello world</span>
</body>
</html>

```

That doesn't look like a response from an nginx server. I think either:

- The domain is pointing at a different server, or
- You have a reverse proxy in front of nginx, which is configured in HTTP/2 cleartext (H2C) mode. This is not compatible with Let's Encrypt ... or browsers.

---

<div class="post-metadata">

**Author:** ![samyan](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/samyan/32/71762_2.png) [@samyan](https://community.letsencrypt.org/u/samyan)\
**Post date:** [July 5, 2023, 12:14pm UTC](https://community.letsencrypt.org/t/certbot-nginx-server-is-speaking-http-2-over-http/201294/3 "2023-07-05T12:14:16Z")

</div>

Thank for response. That is my **/var/www/frontend/index.html** i created for test so the domain is pointing perfectly to the server. And we don't using any reverse proxy. It is a fresh install of Debian. And the first thing we did it was just install nginx and certbot.

---

<div class="post-metadata">

**Author:** ![\_az](https://avatars.discourse-cdn.com/v4/letter/_/22d042/32.png) [@\_az](https://community.letsencrypt.org/u/_az)\
**Post date:** [July 5, 2023, 12:19pm UTC](https://community.letsencrypt.org/t/certbot-nginx-server-is-speaking-http-2-over-http/201294/4 "2023-07-05T12:19:38Z")

</div>

Why is the Server response header missing from the nginx response? It is not possible to disable it in nginx iirc. When that header is missing, it’s generally a dead giveaway for a reverse proxy.

What’s `ss -tlnp` report?

---

<div class="post-metadata">

**Author:** ![samyan](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/samyan/32/71762_2.png) [@samyan](https://community.letsencrypt.org/u/samyan)\
**Post date:** [July 5, 2023, 12:23pm UTC](https://community.letsencrypt.org/t/certbot-nginx-server-is-speaking-http-2-over-http/201294/5 "2023-07-05T12:23:14Z")

</div>

This:

```bash
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process                                                               
LISTEN 0 128 0.0.0.0:9991 0.0.0.0:* users:(("sshd",pid=580,fd=3))                                        
LISTEN 0 3 0.0.0.0:9992 0.0.0.0:* users:(("pure-ftpd",pid=696,fd=4))                                   
LISTEN 0 80 127.0.0.1:3306 0.0.0.0:* users:(("mariadbd",pid=605,fd=21))                                   
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=6361,fd=12),("nginx",pid=6331,fd=12))            
LISTEN 0 128 [::]:9991 [::]:* users:(("sshd",pid=580,fd=4))                                        
LISTEN 0 3 [::]:9992 [::]:* users:(("pure-ftpd",pid=696,fd=5))                                   
LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=6361,fd=13),("nginx",pid=6331,fd=13)) 

```

---

<div class="post-metadata">

**Author:** ![\_az](https://avatars.discourse-cdn.com/v4/letter/_/22d042/32.png) [@\_az](https://community.letsencrypt.org/u/_az)\
**Post date:** [July 5, 2023, 12:23pm UTC](https://community.letsencrypt.org/t/certbot-nginx-server-is-speaking-http-2-over-http/201294/6 "2023-07-05T12:23:43Z")

</div>

Another possibility is that you have another port 80 `server` block that contains something like `listen 80 http2;` or `http2 on;`.

If this is the case, then every single port 80 `server` will be forced into H2C mode, which would result in your issues. You can't mix protocols in that fashion.

If you run `nginx -T` and search through the output for `http2`, it should yield something useful.

---

<div class="post-metadata">

**Author:** ![samyan](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/samyan/32/71762_2.png) [@samyan](https://community.letsencrypt.org/u/samyan)\
**Post date:** [July 5, 2023, 12:47pm UTC](https://community.letsencrypt.org/t/certbot-nginx-server-is-speaking-http-2-over-http/201294/8 "2023-07-05T12:47:40Z")

</div>

You are right my friend!!!

I had another subdomain nginx config (that i didn't include in my previous comments)

`listen 80 http2`

Just removed the `http2` and now is ok!

Thank you very much!

---

<div class="post-metadata">

**Author:** ![rg305](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/rg305/32/91314_2.png) [@rg305](https://community.letsencrypt.org/u/rg305)\
**Post date:** [July 5, 2023, 2:09pm UTC](https://community.letsencrypt.org/t/certbot-nginx-server-is-speaking-http-2-over-http/201294/9 "2023-07-05T14:09:06Z")

</div>

> [@samyan](#):
>
> `return 301 http://$host$request_uri; #renamed from https://$host$request_uri;`

Why renamed from HTTPS?  
That now looks like it will loop all matched HTTP requests back onto itself.

---

<div class="post-metadata">

**Author:** ![samyan](https://sea3.discourse-cdn.com/letsencrypt/user_avatar/community.letsencrypt.org/samyan/32/71762_2.png) [@samyan](https://community.letsencrypt.org/u/samyan)\
**Post date:** [July 5, 2023, 2:20pm UTC](https://community.letsencrypt.org/t/certbot-nginx-server-is-speaking-http-2-over-http/201294/10 "2023-07-05T14:20:48Z")

</div>

When I had the problem, I was trying a thousand things. 😂 Of course in the end, I left it with https. Thanks for commenting!

---

<div class="post-metadata">

**Author:** ![system](https://global.discourse-cdn.com/letsencrypt/original/3X/c/a/ca6c06ea1ea201324bba7048c6841ce60236468d.png) [@system](https://community.letsencrypt.org/u/system)\
**Post date:** [August 4, 2023, 2:21pm UTC](https://community.letsencrypt.org/t/certbot-nginx-server-is-speaking-http-2-over-http/201294/11 "2023-08-04T14:21:41Z")

</div>

Closed on August 4, 2023, 2:21pm UTC

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