1. Contexto y motivo del cambio
A partir de Nginx 1.25.1 (publicado el 4 de julio de 2023), el parámetro http2
ya no se especifica en la directiva listen
. En su lugar, debe activarse con la directiva independiente:
http2 on;
Esto afecta a todas las configuraciones que tengan líneas como:
listen 443 ssl http2;
Si no se actualiza la sintaxis, Nginx mostrará advertencias como:
[warn] the "listen ... http2" directive is deprecated, use the "http2" directive instead
Además, pueden aparecer advertencias del tipo:
protocol options redefined for 0.0.0.0:443
Esto sucede cuando se repiten líneas listen
con opciones distintas para la misma dirección:puerto dentro de un mismo bloque server {}
.
2. Versiones afectadas
- Nginx ≤ 1.25.0: Se permitía y era habitual
listen 443 ssl http2;
. - Nginx ≥ 1.25.1:
http2
solo se activa con la directivahttp2 on;
dentro del bloqueserver {}
.
Fuente: CHANGES nginx-1.25.1.
3. Ejemplo de advertencias reales
Ejemplo de log en Nginx 1.25.x:
2025/08/11 21:59:01 [warn] the "listen ... http2" directive is deprecated, use the "http2" directive instead in /etc/nginx/sites-enabled/site1:27
2025/08/11 21:59:01 [warn] protocol options redefined for 0.0.0.0:443 in /etc/nginx/sites-enabled/site2:9
4. Cambios de sintaxis
Antes (obsoleto)
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name ejemplo.com;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
}
Después (recomendado)
server {
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name ejemplo.com;
ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/key.pem;
}
5. Procedimiento de actualización
5.1 Hacer copia de seguridad
sudo cp -a /etc/nginx/sites-enabled /etc/nginx/sites-enabled.bak.$(date +%F)
5.2 Sustituir ssl http2
por ssl
sudo sed -i -E '
s/(listen[[:space:]]+\[::\]:443[[:space:]]+)([^;]*)(http2)([^;]*);/\1\2\4;/g;
s/(listen[[:space:]]+443[[:space:]]+)([^;]*)(http2)([^;]*);/\1\2\4;/g
' /etc/nginx/sites-enabled/*
5.3 Añadir http2 on;
dentro de cada server {}
que sirva HTTPS
Debe colocarse solo una vez por bloque.
6. Resolución de “protocol options redefined”
Para evitar el mensaje:
protocol options redefined for 0.0.0.0:443
hay que asegurarse de:
- Tener una sola línea
listen 443 ssl;
por IPv4 y otralisten [::]:443 ssl;
por IPv6 en cada bloque. - No duplicar
listen 0.0.0.0:443 ...
con parámetros distintos en el mismoserver {}
. - Usar
default_server
solo en un vhost.
7. Ejemplo práctico: site1.example.com
Antes
server {
server_name site1.example.com;
location / {
proxy_pass http://192.168.1.100:80;
include proxy_params;
}
listen 443 ssl http2;
ssl_certificate /etc/letsencrypt/live/site1.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/site1.example.com/privkey.pem;
}
Después (compatible con Nginx ≥ 1.25.1)
server {
server_name site1.example.com;
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
ssl_certificate /etc/letsencrypt/live/site1.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/site1.example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://192.168.1.100:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
}
access_log /var/log/nginx/access_site1.log;
}
server {
listen 80;
listen [::]:80;
server_name site1.example.com;
return 301 https://$host$request_uri;
}
8. Comprobación y recarga
sudo nginx -t
sudo systemctl reload nginx
Si no hay advertencias, la migración ha sido correcta.
9. Conclusiones
- La directiva
listen ... http2
ha quedado obsoleta en Nginx 1.25.1 y posteriores. - Es obligatorio mover la activación de HTTP/2 a
http2 on;
dentro del bloqueserver {}
. - El mensaje “protocol options redefined” se evita eliminando duplicados y manteniendo la sintaxis consistente.
- Es recomendable revisar todos los vhosts y probar con
nginx -t
antes de recargar el servicio.
Compartir: