2026年11月12日

2026年11月12日

How to Enable HTTP/2 in Nginx: http2 on vs. listen http2

This article is a localized edition of the Japanese original. Read the Japanese original

HTTP/2 is a version of HTTP that can send multiple files in parallel over a single connection, making pages with many images and CSS files load more efficiently. In Nginx you enable it by adding a few lines to the configuration, but the syntax differs by Nginx version, so check your version first.

Major browsers only use HTTP/2 over HTTPS (TLS), so HTTPS must already be set up before your website can use HTTP/2. If it is not yet, first follow "Setting up a Let's Encrypt certificate for Nginx with Certbot".

Check the version and module

# Version
nginx -v

# Is the HTTP/2 module built in? (any output means it is)
nginx -V 2>&1 | grep -o with-http_v2_module

The HTTP/2 module (ngx_http_v2_module) is not built in when you compile from source unless you pass --with-http_v2_module. It is included in the official Ubuntu, Debian and RHEL-family packages and in the packages from nginx.org.

The syntax depends on the version as follows (distribution versions checked as of November 2026):

Nginx version Syntax Examples
1.25.1 and later Add http2 on; to the server block Debian 13 (1.26), current nginx.org packages
1.9.5 to 1.25.0 Add it to listen: listen 443 ssl http2; Ubuntu 24.04 (1.24), Debian 12 (1.22), default on RHEL 9 and Rocky Linux 9 (1.20)

On 1.25.1 and later, listen ... http2 still works, but nginx -t warns: "the "listen ... http2" directive is deprecated". Conversely, writing http2 on; on a version before 1.25.0 fails with the error "unknown directive "http2"" and Nginx will not start.

Configuration example for 1.25.1 and later

Add one line, http2 on;, to the HTTPS server block. The location of the configuration files depends on your setup: on Ubuntu and Debian it is usually /etc/nginx/sites-available/, and on RHEL-based systems and nginx.org packages it is usually under /etc/nginx/conf.d/.

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;

    server_name example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/example.com;
    # existing settings follow
}

http2 can be enabled per server block (if you put it in the http block, it applies to every server inside it).

Configuration example for versions before 1.25.0

Add http2 to the listen lines.

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/example.com;
    # existing settings follow
}

With this syntax, HTTP/2 is enabled per "address and port". If you run several sites on the same port 443, adding http2 to the listen line of any one of them makes the other sites on that port use HTTP/2 too.

In configuration files that Certbot rewrote automatically, it is fine to add http2 to the listen 443 ssl; line (the one marked # managed by Certbot).

Apply the configuration

Check the syntax, then reload. With reload, the change takes effect without dropping visitors who are connected.

sudo nginx -t
sudo systemctl reload nginx

If nginx -t prints syntax is ok and test is successful, it is safe to apply.

Check that HTTP/2 is being used

Check with curl

curl -sI --http2 https://example.com/ | head -1

If the first line is HTTP/2 200, the server is responding over HTTP/2. If it still shows HTTP/1.1 200 OK, the configuration has not been applied or a different server block is answering.

Check the access log

With the default log format, the protocol is recorded in the request line.

"GET / HTTP/2.0" 200 896 "-" "curl/8.14.1"

If it is logged as HTTP/2.0, the request used HTTP/2.

Check in the browser

In the "Network" tab of the Chrome or Firefox developer tools, right-click a column header and show "Protocol"; HTTP/2 requests are shown as h2.

Things to watch out for

  • HTTP/2 server push is not available: HTTP/2 server push was removed in 1.25.1, and http2_push and http2_push_preload no longer work. Do not add the http2_push settings found in older articles.
  • If you use a CDN such as Cloudflare: The CDN handles the connection with visitors' browsers, so the browser developer tools show the protocol between the browser and the CDN. To check your own server's configuration, look at the server's access log.
  • If you set ssl_ciphers yourself: The official Nginx documentation says that when ssl_prefer_server_ciphers on is set, ssl_ciphers should comply with Appendix A of RFC 9113 (the list of ciphers that must not be used with HTTP/2) and be supported by clients. If you are still using an old cipher list, review it.

Summary

  • Check the version with nginx -v: use http2 on; for 1.25.1 and later, and listen 443 ssl http2; for earlier versions
  • HTTPS must be set up before you can use HTTP/2
  • Check with sudo nginx -t, then apply with sudo systemctl reload nginx
  • Confirm with the first line of curl -sI --http2 or HTTP/2.0 in the access log

If you are also reviewing compression settings for WordPress on Nginx, see "Nginx gzip and HTTP/2 settings for WordPress".

Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲