Skip to content

How to Fix Nginx HTTP/2 Not Working Error

DodaTech Updated 2026-06-24 2 min read

In this tutorial, you'll learn about How to Fix Nginx HTTP/2 Not Working Error. We cover key concepts, practical examples, and best practices.

Nginx responds with HTTP/1.1 instead of HTTP/2 even though http2 is configured — browsers show h2 in the :scheme pseudo-header is not working or the ALPN negotiation fails.

The Problem

$ curl -I --http2 http://localhost/
# Response uses HTTP/1.1 instead of HTTP/2
HTTP/1.1 200 OK

Step-by-Step Fix

Step 1: Enable HTTP/2 correctly

# Correct for Nginx 1.25+
server {
    listen 443 ssl;
    http2 on;  # or http2 on;
    # ...
}

# Correct for older Nginx (< 1.25)
server {
    listen 443 ssl http2;
    # ...
}

Step 2: Verify HTTP/2 is compiled in

nginx -V 2>&1 | grep -o http_v2

Expected: http_v2

Step 3: Check ALPN configuration

ssl_protocols TLSv1.2 TLSv1.3;  # HTTP/2 requires TLSv1.2+
ssl_ciphers HIGH:!aNULL:!MD5;

Step 4: Test with curl

curl -v --http2 https://example.com/ 2>&1 | grep -i "alpn\|http2"

Expected:

* ALPN: offers h2,http/1.1
* ALPN: server accepted h2
* Using HTTP/2

Step 5: Test with openssl

openssl s_client -connect localhost:443 -alpn h2 -tlsextdebug

Prevention Tips

  • Use OpenSSL 1.0.2+ for ALPN support (required for HTTP/2)
  • Enable HTTP/2 only on HTTPS (browsers do not support h2c)
  • Test with curl --http2-prior-knowledge for clear-text HTTP/2
  • Verify HTTP/2 with Chrome DevTools Network tab (Protocol column)

Common Mistakes with http2 not working

  1. Forgetting deriving (Show, Eq) on custom data types needed for debugging
  2. Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
  3. Using head and tail instead of pattern matching, causing runtime errors on empty lists

These mistakes appear frequently in real-world NGINX code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### Why does Nginx respond with HTTP/1.1 even with http2 enabled?

On Nginx versions before 1.25, http2 must be on the listen directive: listen 443 ssl http2;. On versions 1.25+, use http2 on; as a separate directive. Also verify that nginx -V includes http_v2 and OpenSSL supports ALPN.

Does HTTP/2 work on port 80 in Nginx?

HTTP/2 over cleartext (h2c) is supported in Nginx but is rarely used in production. Browsers do not support h2c; they only use HTTP/2 over TLS (h2). For server-to-server communication, h2c can be useful but requires explicit curl with --http2-prior-knowledge.

How do I verify HTTP/2 is actually being used?

Use Chrome DevTools (Network tab, Protocol column shows h2), or run curl -v --http2 https://example.com/ and look for Using HTTP/2 in the output. Also check Nginx access logs for the $server_protocol variable.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro