Servidores

La Controversia del Modo Oscuro en Nginx: por qué sigue sin soporte

En marzo de 2025 el upstream de Nginx rechazó un PR de una línea que agregaba <meta name="color-scheme" content="light dark"> a las páginas de error. Un año después, con una encuesta comunitaria que dio 579 votos a favor contra 59 en contra, el PR sigue cerrado sin explicación. Te contamos por qué pasó, qué puedes hacer hoy y qué vigilar.


TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 1-2 horas para servidor limpio, 30-60 minutos con Ansible.
  • Requisitos: VPS Linux, 2+ GB RAM, 20+ GB SSD, dominio con DNS.
  • Resultado: nginx + PHP-FPM + MariaDB + Let’s Encrypt, throughput alto.
  • Troubleshooting: nginx -T, systemctl status nginx, journalctl -u nginx.

Índice

  1. El origen: el PR #567 de marzo de 2025
  2. La encuesta que ganó por landslide y luego quedó en silencio
  3. Por qué Nginx dice que no: el argumento de “mantener simple”
  4. Qué proponía exactamente el PR original
  5. Cómo personalizar tus propias páginas de error hoy
  6. Tres patrones oscuros que sí funcionan (con prefers-color-scheme)
  7. Workaround completo: una 404 dark mode lista para copiar
  8. Por qué este silencio importa a la comunidad Linux
  9. Qué viene después: PR #567, fork open source y vigilancia

1. El origen: el PR #567 de marzo de 2025

El 11 de marzo de 2025 alguien abrió en el repositorio oficial github.com/nginx/nginx el pull request #567. Era un cambio pequeño. La descripción decía: “add color-scheme meta tag to default error pages for native dark mode support”. El diff modificaba los archivos HTML que Nginx sirve cuando ocurre un error 4xx/5xx — 404.html, 500.html, 502.html, 503.html y el resto del grupo — y agregaba una sola etiqueta en el <head>:

<meta name="color-scheme" content="light dark">

Lo que hace: le dice al navegador “esta web es compatible con esquemas de color claro y oscuro, deja que el sistema operativo elija”. Es la misma etiqueta que ya usan hace años sitios como GitHub, MDN, Wikipedia y prácticamente cualquier proyecto open source medianamente moderno. No requiere CSS adicional. No cambia el diseño. No agrega dependencias. Solo le pide al browser que respete la configuración del usuario.

El 17 de marzo de 2025 el PR fue cerrado. El argumento, según el comentario del maintainer, fue que las páginas de error por defecto de Nginx están diseñadas para ser mínimas y que agregar una etiqueta extra era “superfluo”. La recomendación al usuario que reportó el issue fue: si no te gusta la página de error por defecto, usa la directiva error_page y serví tu propia versión.

2. La encuesta que ganó por landslide y luego quedó en silencio

El cierre del PR generó backlash inmediato en Hacker News, Reddit y Lobsters. Pocos días después, un empleado de F5 (la empresa detrás de Nginx) abrió la discusión #584 con una encuesta directa: “¿quieres soporte de dark mode en las páginas de error de Nginx?”. El resultado fue contundente:

  • 579 pulgares arriba
  • 59 pulgares abajo
  • Decenas de comentarios y otras reacciones

Una proporción de 9 a 1 a favor. En junio de 2025 alguien preguntó en la discusión #722 si había alguna conclusión derivada de la encuesta. Cero respuestas de los maintainers. Tiempo después, en la discusión #759, se volvió a preguntar. Mismo resultado: silencio.

El PR #567 sigue marcado como “locked” en GitHub. No fue reabierto, no fue mergeado, no fue marcado como “won’t fix” formalmente. Simplemente está ahí, congelado, mientras Nginx sigue sirviendo sus páginas de error en blanco brillante sobre fondo blanco cuando tu OS está en dark mode.

3. Por qué Nginx dice que no: el argumento de “mantener simple”

La postura oficial implícita (no hay documento escrito, pero se deduce de los comentarios en el PR) es que Nginx es un servidor web de propósito general cuyo objetivo principal es servir archivos estáticos y hacer proxy reverso de manera eficiente. Las páginas de error por defecto son una red de seguridad: aparecen solo cuando algo se rompió aguas arriba. Mantenerlas deliberadamente simples — sin CSS, sin scripts, sin lógica condicional — significa que:

  • El HTML servido no agrega bytes que podrían amplificar un ataque (si Nginx está bajo presión, cada byte cuenta).
  • El usuario que ve la página recibe información mínima y clara: código de error, descripción corta, y ya.
  • El servidor no gasta ciclos renderizando nada fancy — solo emite HTML estático desde ngx_http_special_response.c.

El argumento tiene sentido si lo mirás desde el lado de la ingeniería de sistemas. Pero choca de frente con una realidad de 2026: la mayoría de los navegadores modernos ya respetan la preferencia de dark mode a nivel sistema operativo. Un usuario que navega con tema oscuro y se topa con una página blanca pura con texto negro chico y Times New Roman siente que algo se rompió. Y “algo se rompió” es exactamente la sensación que una página de error 404 NO debería transmitir.

4. Qué proponía exactamente el PR original

El cambio era quirúrgico. Toma como ejemplo la página de error 404 estándar de Nginx (truncada para brevedad):

<html>
<head>
<title>404 Not Found</title>
</head>
<body>
<center><h1>404 Not Found</h1></center>
<center>nginx/1.27.0</center>
</body>
</html>

El PR #567 proponía agregar la etiqueta <meta name="color-scheme" content="light dark"> dentro del <head>:

<html>
<head>
<meta name="color-scheme" content="light dark">
<title>404 Not Found</title>
</head>
<body>
<center><h1>404 Not Found</h1></center>
<center>nginx/1.27.0</center>
</body>
</html>

Sin CSS adicional, sin cambios de diseño. El navegador, al recibir esa meta etiqueta, aplica automáticamente el color scheme que coincide con la preferencia del sistema operativo. Si el usuario tiene dark mode activo, el navegador pinta fondo oscuro y texto claro sobre los elementos que usan los colores por defecto. Si está en light mode, todo sigue igual que antes. Es la solución más minimalista posible al problema.

Y aún así fue rechazada.

5. Cómo personalizar tus propias páginas de error hoy

La respuesta oficial de Nginx es válida: usa la directiva error_page. La sintaxis es simple y te permite apuntar cada código HTTP a un archivo local:

server {
    listen 80;
    server_name ejemplo.com;
    root /var/www/ejemplo;
    # Páginas de error personalizadas en /var/www/ejemplo/errors/
    error_page 404 /errors/404.html;
    error_page 500 502 504 /errors/50x.html;
    error_page 403 /errors/403.html;
    location ^~ /errors/ {
        internal;          # solo accesible vía internal redirect de error_page
        root /var/www/ejemplo;
    }
}

Lo que hace: cuando Nginx genera una respuesta 404 para una request, redirige internamente a /errors/404.html en lugar de servir el HTML por defecto. Por qué importa: el flag internal impide que un usuario externo acceda directamente a tus páginas de error escribiendo https://ejemplo.com/errors/404.html — solo Nginx puede servirlas tras un error. Troubleshooting: si la página no se ve, verifica que el archivo exista y tenga permisos de lectura para el usuario con el que corre Nginx (típicamente www-data en Debian/Ubuntu, nginx en RHEL/Fedora).

6. Tres patrones oscuros que sí funcionan

Una vez que tienes tus propias páginas de error servidas por Nginx, el resto es HTML y CSS. Estos son los tres patrones más comunes que usan sitios en producción hoy, en orden de complejidad creciente.

Patrón 1 — solo la meta etiqueta. Es lo que proponía el PR original y es suficiente si no quieres tocar nada más:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="color-scheme" content="light dark">
<title>404 — Página no encontrada</title>
</head>
<body>
<h1>404</h1>
<p>La página que buscás no existe.</p>
</body>
</html>

Lo que hace: el navegador aplica automáticamente el color scheme del sistema operativo. Por qué importa: cero CSS custom, máxima compatibilidad. Troubleshooting: algunos navegadores viejos (Safari pre-15, Firefox pre-96) no respetan la meta etiqueta. Si tu audiencia incluye usuarios en esos browsers, pasa al patrón 2.

Patrón 2 — CSS con prefers-color-scheme. Acá tomas control del diseño pero respetás la preferencia del usuario:

<style>
  :root {
    --bg: #ffffff;
    --fg: #1a1a1a;
  }
  @media (prefers-color-scheme: dark) {
    :root {
      --bg: #1a1a1a;
      --fg: #e6e6e6;
    }
  }
  body { background: var(--bg); color: var(--fg); font-family: system-ui, sans-serif; }
</style>

Lo que hace: detecta la preferencia de dark mode y aplica la paleta correspondiente usando custom properties. Por qué importa: puedes ajustar el diseño sin escribir dos hojas de estilo. Troubleshooting: si tu página de error está embebida en un iframe o heredando CSS de otro sitio, las custom properties pueden chocar. Aislá el CSS con un selector más específico (html body en lugar de solo body) o usa !important en las reglas críticas.

Patrón 3 — control total con switch manual. Para sitios donde quieres que el usuario pueda override la preferencia del sistema:

<button onclick="document.documentElement.dataset.theme =
  document.documentElement.dataset.theme === 'dark' ? 'light' : 'dark'">
  Cambiar tema
</button>
<style>
  html[data-theme="light"] { --bg: #fff; --fg: #111; }
  html[data-theme="dark"]  { --bg: #111; --fg: #eee; }
</style>

Lo que hace: agrega un botón que alterna entre dos temas independientes de la preferencia del sistema. Por qué importa: algunos usuarios tienen el sistema en dark mode pero prefieren una página de error clara, o viceversa. Troubleshooting: el botón necesita JavaScript habilitado. Si tu audiencia incluye entornos donde JS está desactivado (curl, scripts de monitoring, algunos crawlers), agrega un fallback con <noscript> que aplique solo la meta etiqueta del patrón 1.

7. Workaround completo: una 404 dark mode lista para copiar

Si quieres algo que puedes pegar en /var/www/ejemplo/errors/404.html hoy y que funcione en todos los navegadores modernos, esta es la versión que recomendamos. Combina el patrón 1 (meta etiqueta) con el patrón 2 (CSS con prefers-color-scheme) y un poco de estilo para que la página no se vea como algo de los 90s:

<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="light dark">
<meta name="robots" content="noindex">
<title>404 — Página no encontrada</title>
<style>
  :root {
    --bg: #ffffff;
    --fg: #1a1a1a;
    --muted: #666;
    --accent: #0066cc;
  }
  @media (prefers-color-scheme: dark) {
    :root {
      --bg: #121212;
      --fg: #e6e6e6;
      --muted: #999;
      --accent: #4d9fff;
    }
  }
  body {
    background: var(--bg);
    color: var(--fg);
    font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
    max-width: 32rem;
    margin: 4rem auto;
    padding: 0 1rem;
    line-height: 1.5;
  }
  h1 { font-size: 4rem; margin: 0; color: var(--accent); }
  p.muted { color: var(--muted); font-size: 0.9rem; }
  a { color: var(--accent); }
</style>
</head>
<body>
<h1>404</h1>
<p>La página que buscás no existe o fue movida.</p>
<p class="muted">Si llegaste acá desde un link, avisale al dueño del sitio.</p>
<p><a href="/">Volver al inicio</a></p>
</body>
</html>

Lo que hace: declara dos paletas (light/dark) usando custom properties que responden a prefers-color-scheme, agrega la meta etiqueta color-scheme como red de seguridad para browsers viejos, e incluye noindex para que Google no indexe páginas de error. Por qué importa: es copy-paste friendly, no tiene dependencias, y funciona en cualquier servidor Nginx con la directiva error_page configurada. Troubleshooting: si ves texto borroso en dark mode en Safari, agrega -webkit-font-smoothing: antialiased al selector body.

8. Por qué este silencio importa a la comunidad Linux

Más allá del caso puntual de Nginx, lo que está en juego es cómo el open source maneja los pequeños fixes de UX que benefician a una mayoría silenciosa. La encuesta dio 579 a 59 a favor, lo que sugiere que el beneficio es claro para quien lo usa. La objeción técnica (“sumar bytes al error page”) es válida pero marginal: una etiqueta <meta> suma 41 bytes. La objeción estética (“mantener simple”) es filosófica, no técnica.

El patrón que vemos en otros proyectos open source es distinto. Caddy, el servidor web escrito en Go que creció como alternativa moderna a Nginx, sí incluye dark mode automático en sus páginas de error desde la versión 2.6. Traefik, el reverse proxy popular en Kubernetes, también respeta la meta etiqueta color-scheme en su dashboard por defecto. Es decir: el problema que Nginx dice no querer resolver, otros proyectos lo resolvieron sin traumas. La pregunta que queda flotando es si Nginx está esperando que el problema se haga más visible o si simplemente no le importa lo suficiente.

Para los sysadmins que están del lado del despliegue, la lección práctica es: no esperes que Nginx cambie de opinión. Si quieres dark mode en tus páginas de error, implementalo tú con error_page y un poco de CSS. Es media hora de trabajo y queda mejor que cualquier cosa que un PR podría ofrecer.

9. Qué viene después: PR #567, fork open source y vigilancia

Lo que podemos esperar en los próximos meses:

  • Que el PR #567 siga congelado. El patrón histórico muestra que cuando un PR open source pasa más de 12 meses sin movimiento, es muy raro que se reactive. La energía de la comunidad se dispersa y el tema pierde prioridad.
  • Que aparezca un fork “Nginx Dark” no oficial. Es el patrón clásico: cuando un proyecto grande ignora un fix menor, alguien hace el fork y lo mantiene como patch set. Ya hay varias personas en la discusión #759 proponiendo esta solución.
  • Que la competencia siga capturando usuarios. Caddy y Traefik ya ofrecen la feature. Para nuevos proyectos greenfield en 2026, la pregunta “¿cuál servidor web uso?” tiene cada vez más respuesta “Caddy” y menos “Nginx”. El dark mode es solo una de las razones.

Si te importa el tema, lo más útil que puedes hacer es:

  1. Suscribirte al PR #567 y a las discusiones #584, #722, #759 en GitHub para recibir notificaciones si se mueven.
  2. Votar thumbs up en la discusión #584 si no lo hiciste.
  3. Implementar tu propia versión con error_page mientras tanto.

Y si Nginx nunca cambia de opinión, al menos queda el consuelo de saber que la solución estaba ahí desde el día uno, esperando a alguien que la implementara.


Preguntas frecuentes

¿Por qué La Controversia del Modo Oscuro en Nginx: por qué sigue sin soporte es relevante para sysadmins Linux?

Forma parte del flujo diario de administración. Los conceptos explicados se aplican directamente a servidores en producción y resuelven problemas reales que enfrentan sysadmins hispanohablantes.

¿Qué necesito para empezar con La Controversia del Modo Oscuro?

Distribución Linux actualizada (Debian, Ubuntu, RHEL, Fedora o Arch), acceso root, y conexión a internet. Para producción: entorno de staging separado antes de aplicar cambios.

¿Cuáles son los errores más comunes con La Controversia del Modo Oscuro?

Los tres más frecuentes: (1) saltar la lectura de logs, (2) aplicar cambios directos en producción sin probar, (3) olvidar permisos y ownership. La documentación y un plan de rollback siempre.

¿Cuándo usar La Controversia del Modo Oscuro y cuándo una alternativa?

Esta solución es ideal para el caso descrito. Alternativas como Docker, Ansible o configuración manual pueden ser mejores según contexto: portabilidad, escala y reproducibilidad son los factores clave.

¿Cómo migro desde una configuración previa a La Controversia del Modo Oscuro?

Documentar el estado actual, probar la nueva configuración en staging, validar funcionalmente, y aplicar en producción con rollback plan listo. Los posts de SoyLinux incluyen troubleshooting para los problemas más comunes.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

One thought on “La Controversia del Modo Oscuro en Nginx: por qué sigue sin soporte”

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *