How to Enable HTTP/2 in Nginx (the http2-on Syntax, the Legacy Trap, and the Verify Step)
CodexFuse Team · 2026-11-04T07:53:00.286Z · 9 min read min read
To enable HTTP/2 in Nginx, you add one directive to your site's HTTPS server block — but which directive depends on your Nginx version. Nginx 1.25.1 and newer use the standalone http2 on; directive, while 1.9.5 through 1.25.0 use the legacy listen 443 ssl http2; parameter. Mixing them up is the single most common failure: the new directive is an "unknown directive" error on older builds, and the old parameter triggers a deprecation warning on new ones. This guide walks through checking your version, picking the right syntax, editing the server block, and verifying that clients actually negotiate HTTP/2 — the step most tutorials skip.
If you are tuning a self-hosted site, pair this with our gzip compression guide — compression and HTTP/2 are the two highest-leverage server-side speed wins, and they stack.
How Do You Enable HTTP/2 in Nginx?
You enable HTTP/2 by confirming the module is compiled in, adding the version-correct directive to your HTTPS server block, testing the config, reloading Nginx, and then verifying the negotiated protocol. The whole job takes about ten minutes on a typical VPS hosting setup.
- Check your Nginx version with
nginx -v. Version 1.25.1 or newer takeshttp2 on;; 1.9.5 through 1.25.0 takes the legacylisten 443 ssl http2;form. - Confirm the HTTP/2 module is built in with
nginx -V 2>&1 | grep -o with-http_v2_module. No output means you need a rebuild or a different package. - Edit the HTTPS server block for your site — add
http2 on;inside theserver { }block (1.25.1+), or add thehttp2parameter to thelisten 443 sslline (older). - Test and reload:
sudo nginx -t && sudo systemctl reload nginx. - Verify the protocol actually negotiated with
curl -I --http2 https://yourdomain.comand look forHTTP/2 200in the first response line. A clean config test alone does not prove HTTP/2 is serving.
Which HTTP/2 Syntax Does Your Nginx Version Need?
Your Nginx version decides the syntax — there is no universal form. Nginx 1.25.1, released 13 June 2023, introduced the standalone http2 directive and deprecated the http2 parameter on the listen directive, per the official changelog. Use the wrong one and Nginx either refuses to start or logs a deprecation warning on every reload.
| Your Nginx version | Syntax to use | What happens if you use the other form |
|---|---|---|
| 1.25.1 and newer | listen 443 ssl; plus http2 on; inside the server block | The legacy listen 443 ssl http2; still parses but logs a deprecation warning |
| 1.9.5 through 1.25.0 | listen 443 ssl http2; | http2 on; fails with unknown directive "http2" and Nginx will not start |
| Older than 1.9.5 | Neither — upgrade first | No HTTP/2 module exists in these builds |
I reproduced the failure mode on a real server running Nginx 1.24.0: the legacy block passed nginx -t cleanly, while adding http2 on; produced unknown directive "http2" and a failed test. Check the version before you copy any config snippet — including the ones in this article.
How Do You Check That the HTTP/2 Module Is Installed?
Run nginx -V (capital V) and look for --with-http_v2_module in the configure arguments. The module provides HTTP/2 support starting from Nginx 1.9.5, but the official docs note it is not built by default — it must be enabled with the --with-http_v2_module configuration parameter.
In practice, the Nginx packages shipped by Ubuntu and Debian include the module, so most VPS installs pass this check immediately. A minimal source build or a stripped container image may not. If the flag is missing, your options are reinstalling from a package that includes it or recompiling with --with-http_v2_module added to the configure line.
nginx -V 2>&1 | grep -o -- '--with-http_v2_module'
# prints --with-http_v2_module if the module is compiled in
How Do You Edit the Server Block?
Edit the server block that serves your HTTPS site — typically in /etc/nginx/sites-available/your-site on Debian/Ubuntu or /etc/nginx/conf.d/ elsewhere. If you are still learning Nginx configuration layout, our Nginx beginner guide covers server blocks in detail.
On Nginx 1.25.1 and newer, keep the listener clean and put HTTP/2 on its own directive. This matches the official module documentation's example configuration:
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name example.com www.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# ... rest of your site configuration
}
The http2 directive defaults to off and is valid in the http and server contexts, so placing it inside the server block enables HTTP/2 for that virtual host only. Do not add it to the port-80 block — that block should only redirect to HTTPS.
On Nginx 1.9.5 through 1.25.0, add the http2 parameter to each HTTPS listener instead:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# ... rest of your site configuration
}
After editing, always run sudo nginx -t before reloading. Then apply with sudo systemctl reload nginx (a reload, not a restart, avoids dropping connections).
Does HTTP/2 Require HTTPS?
In practice, yes. The HTTP/2 specification technically defines a cleartext mode called h2c, and Nginx's own $http2 variable distinguishes h2 (HTTP/2 over TLS) from h2c (HTTP/2 over cleartext TCP) — but every major browser enforces HTTPS-only for HTTP/2 and will never negotiate h2c.
That means your site needs a working TLS certificate before HTTP/2 does anything for browser traffic. HTTP/2 over TLS also requires ALPN (Application-Layer Protocol Negotiation) support, which the Nginx docs say is available since OpenSSL 1.0.2 — any maintained distro ships something far newer, so this is only a concern on ancient systems. One more TLS detail from the official docs: if ssl_prefer_server_ciphers is on, your cipher list must comply with the RFC 9113 Appendix A blacklist, because HTTP/2 forbids weak ciphers and misconfigured suites will cause connection failures even with the directive correct.
How Do You Verify HTTP/2 Is Actually Working?
A passing nginx -t only proves the syntax is valid — it says nothing about what clients negotiate. Verify with a real request. The fastest check is curl:
curl -I --http2 https://yourdomain.com
# look for "HTTP/2 200" as the first response line
If the first line reads HTTP/1.1 200 instead, HTTP/2 is not active for that virtual host — recheck the server block you edited (a common mistake is editing the wrong server block when several share port 443).
For a browser-side confirmation, open Chrome DevTools, go to the Network tab, right-click the column headers, enable the Protocol column, and reload the page. Resources served over HTTP/2 show h2; anything still on http/1.1 needs investigation. Server-side, you can log the negotiated protocol with Nginx's $http2 variable, which the docs define as h2 for HTTP/2 over TLS, h2c for cleartext, or empty otherwise.
What Breaks Most Often When Enabling HTTP/2?
Four failure modes cover nearly every broken setup. First, the version-syntax mismatch: unknown directive "http2" means you used the new directive on Nginx older than 1.25.1 — switch to the legacy listen parameter. Second, the deprecation warning on 1.25.1+: harmless but noisy; move http2 off the listen line onto its own directive.
Third, the missing module: if nginx -V shows no --with-http_v2_module, no directive will help until the binary is replaced. Fourth, TLS problems masquerading as HTTP/2 problems: an expired certificate, missing ALPN, or a blacklisted cipher suite will break the handshake before HTTP/2 is ever negotiated, so always confirm plain HTTPS works first.
One thing not to reach for: server push. The http2_push directives were made obsolete in 1.25.1 and HTTP/2 server push support was removed in that same release, with the docs pointing to early_hints (103 Early Hints) instead. Tutorials that still recommend http2_push are teaching a dead feature — skip them.
Sources
All technical claims above were verified against these sources on 4 November 2026:
- Nginx official documentation, "Module ngx_http_v2_module" —
http2 on | offsyntax, defaultoff,http/servercontext, appeared in 1.25.1;--with-http_v2_modulebuild flag; ALPN requires OpenSSL 1.0.2+; cipher compliance with RFC 9113 Appendix A;$http2variable values (h2/h2c/empty);http2_pushfamily obsolete since 1.25.1 — https://nginx.org/en/docs/http/ngx_http_v2_module.html - Nginx official changelog — 1.25.1 (13 Jun 2023): 'the "http2" directive, which enables HTTP/2 on a per-server basis; the "http2" parameter of the "listen" directive is now deprecated' and 'HTTP/2 server push support has been removed'; current release 1.31.8 (21 Oct 2026) — https://nginx.org/en/CHANGES
- LinuxCapable, "Enable HTTP/2 in Nginx: http2 on and Legacy Syntax" (16 days old) — version-split decision table, module check via
nginx -V, rollback guidance — https://linuxcapable.com/how-to-enable-http2-in-nginx/ - LinuxBlog.io, "Nginx tuning tips: HTTPS/TLS" (147 days old) — the 1.25.1 migration (
listen 443 ssl http2tohttp2 on), fleet-upgrade warning — https://linuxblog.io/nginx-tuning-tips-tls-ssl-https-ttfb-latency/ - SSLInsights, "How to Enable HTTP/2 in Nginx (Step-by-Step) [2026]" (169 days old) —
curl -I --http2verification showingHTTP/2 200, every-major-browser-enforces-HTTPS statement, RFC 7540 cipher-blacklist note — https://sslinsights.com/how-to-enable-http2-on-nginx-web-server/ - UmaTechnology, "Enable HTTP/2 in Apache and Nginx" (35 days old) — ALPN prerequisite, validate-before-reload, syntax-acceptance-is-not-enough verification framing — http://umatechnology.org/how-to-enable-http-2-in-apache-and-nginx/
- Author's own server test (4 Nov 2026) — Nginx 1.24.0 (Ubuntu): legacy
listen 443 ssl http2;block passednginx -t; addinghttp2 on;failed withunknown directive "http2", confirming the version split empirically.
Frequently Asked Questions
How do I enable HTTP/2 in Nginx?
Add the version-correct directive to your HTTPS server block: http2 on; inside the server block on Nginx 1.25.1+, or the http2 parameter on listen 443 ssl for 1.9.5–1.25.0. Then run nginx -t, reload, and verify with curl -I --http2.
What is the http2 on directive in Nginx?
It is the standalone directive introduced in Nginx 1.25.1 that enables HTTP/2 on a per-server basis. It replaced the older http2 parameter on the listen directive, which is now deprecated. It defaults to off and goes in the http or server context.
How do I check if HTTP/2 is enabled in Nginx?
Run curl -I --http2 https://yourdomain.com and check that the first response line says HTTP/2 200. In Chrome DevTools, the Network tab's Protocol column shows h2 for HTTP/2 resources. Server-side, Nginx's $http2 variable logs the negotiated protocol.
Does HTTP/2 require HTTPS in Nginx?
For browser traffic, effectively yes — every major browser only negotiates HTTP/2 over TLS, even though the spec defines a cleartext mode (h2c). You need a valid certificate and ALPN support (OpenSSL 1.0.2+) before HTTP/2 will serve browsers.
Why does Nginx say "unknown directive http2"?
Your Nginx is older than 1.25.1, which is the first version with the standalone http2 directive. Use the legacy form — listen 443 ssl http2; — or upgrade Nginx to 1.25.1 or newer.

