Cómo resolver: docker: Error response from daemon: driver failed programming external connectivity

Corres docker run o docker compose up, la imagen se descarga bien, el contenedor se crea… y todo explota en el último paso:

docker: Error response from daemon: driver failed programming external connectivity on 
endpoint webserver(a1b2c3d4e5f6...): Error starting userland proxy: listen
tcp4 0.0.0.0:8080: bind: address already in use.

Este error es especialmente frustrante porque el mensaje es genérico —"failed programming external connectivity"— pero esconde causas muy distintas entre sí. Vamos a diagnosticarlo correctamente en vez de probar comandos al azar, porque copiar una solución que no corresponde a tu causa real (algo muy común en foros) puede dejarte peor que antes.

Por qué el mensaje es tan poco específico

Docker envuelve varios errores de red bajo el mismo prefijo. "Error response from daemon" es la forma en que Docker te indica que el daemon rechazó tu solicitud; es un envoltorio genérico sobre docenas de errores distintos, desde imágenes faltantes hasta problemas de permisos o agotamiento de recursos. La causa real siempre está en la parte del mensaje que sigue al prefijo, así que lo primero es leer la línea completa, no solo el título del error.

Con "driver failed programming external connectivity" hay tres familias de causas, en orden de frecuencia:

  1. El puerto que querés exponer ya está en uso.
  2. Las reglas de iptables/nftables de Docker se corrompieron o fueron eliminadas.
  3. Hay estado de red obsoleto (sockets huérfanos, pools de IP agotados).

Causa 1: el puerto ya está ocupado

Es la causa más común, y por suerte la más fácil de confirmar. Este error suele deberse a un conflicto de puerto o a reglas de firewall que impiden que Docker se enlace al puerto solicitado. Ocurre cuando Docker intenta enlazar un puerto del host que otro proceso ya está usando —puede ser otro contenedor, un servicio local, o un proceso que quedó colgado de una ejecución anterior.

Verifica qué está usando el puerto:

sudo lsof -i :8080

O, si lsof no está disponible en tu Debian/Ubuntu:

sudo ss -tulpn | grep 8080

Con el PID que aparece, tenés dos caminos: matar el proceso conflictivo o cambiar el puerto de tu contenedor. Lo segundo suele ser más seguro cuando no sabés qué es ese otro proceso:

docker run -p 8081:8080 tu-imagen

Si el conflicto viene de otro contenedor Docker que quedó corriendo:

docker ps
docker stop <nombre_o_id>

Caso especial con Docker Compose: el mensaje cambia un poco de forma pero es la misma causa raíz:

Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:3000 -> 0.0.0.0:0: listen tcp 0.0.0.0:3000: bind: address already in use

El error significa que algo más en tu sistema ya reclamó ese puerto. El diagnóstico es idéntico: lsof o ss, y después liberar el puerto o cambiarlo en tu docker-compose.yml.

Causa 2: Docker perdió su conexión con iptables/nftables

Esta es la causa que más desconcierta, porque el contenedor que ayer funcionaba hoy falla sin que hayas tocado nada del Dockerfile ni del compose. El mensaje suele verse así:

(iptables failed: iptables --wait -t filter -A DOCKER ! -i docker0 -o docker0 -p tcp -d 172.17.0.2 --dport 443 -j ACCEPT: iptables: No chain/target/match by that name. (exit status 1))

Esto suele pasar cuando actualizás las reglas de iptables mientras Docker está corriendo. En Linux, Docker crea o modifica reglas de iptables para aislar la red de los contenedores, agregando esas reglas a una cadena llamada DOCKER. Si algo —un firewall que se reinició, un script de hardening, o una herramienta de gestión de servidor como Plesk— borra o reemplaza esa cadena, Docker pierde su correlación con iptables y el error aparece.

La causa más frecuente en servidores Debian gestionados: un proceso externo (por ejemplo, parte de un panel de control) elimina las reglas de iptables y las vuelve a agregar, rompiendo la cadena DOCKER que Docker había creado.

La solución que funciona en la enorme mayoría de los casos:

sudo systemctl restart docker

Al reiniciar Docker, el servicio recrea automáticamente sus reglas de firewall. Si tu servidor tiene UFW o firewalld activo, asegurate de que esté habilitado antes de reiniciar Docker, para que las reglas se generen sobre una base consistente.

Si el problema vuelve a aparecer después de cada reinicio de tu firewall o de tu panel de administración, el problema de fondo no es Docker: es que algo en tu stack sigue flushando las reglas. Lo importante es mantener un solo backend de firewall de forma consistente —no mezclar iptables-legacy con nftables— y dejar que Docker gestione sus propias cadenas.

Para confirmar que el problema es específicamente el backend de iptables/nftables, revisá los logs del daemon:

journalctl -u docker | grep -i iptables

Causa 3: estado de red obsoleto o pools de IP agotados

Menos común, pero típico en servidores CI/CD o en máquinas donde se crean y destruyen muchos contenedores/redes sin limpiar. El mensaje varía:

Error response from daemon: failed to set up container networking: could not find an available,
non-overlapping IPv4 address pool among the defaults to assign to the network.

Esto pasa cuando se crearon suficientes redes personalizadas como para agotar los pools de direcciones por defecto, algo común en pipelines de CI que crean una red nueva por cada build y nunca las eliminan.

Diagnóstico:

docker network ls
docker network inspect bridge | grep -i 'subnet\|gateway\|address'

Si ves decenas de redes que ya no usás, límpialas:

docker network prune -f

Otra variante de esta causa raíz es un estado de socket huérfano tras un apagado no limpio del daemon. Un apagado no ordenado puede dejar endpoints o sandboxes de red haciendo referencia a IPs que ya no están libres. La solución rápida:

sudo systemctl restart docker

Y si persiste, como último recurso, recreá la red específica que da problemas:

docker network rm nombre_de_la_red
docker network create nombre_de_la_red

Tabla de diagnóstico rápido

Mensaje que ves después del prefijo Causa más probable Primer comando a correr
Bind for 0.0.0.0:PUERTO failed: port is already allocated Puerto ocupado por otro contenedor Docker docker ps
bind: address already in use Puerto ocupado por un proceso del sistema sudo lsof -i :PUERTO
iptables: No chain/target/match by that name Reglas de iptables de Docker corrompidas sudo systemctl restart docker
could not find an available, non-overlapping IPv4 address pool Pools de red agotados docker network prune -f
failed to allocate gateway Conflicto de subred (VPN o red corporativa) docker network inspect bridge

El contraargumento: ¿reiniciar Docker es "arreglar" o solo "posponer"?

Vale la pena decirlo con claridad: systemctl restart docker es una solución legítima y ampliamente recomendada para la corrupción de cadenas de iptables, no un parche sucio. Pero si el problema reaparece cada pocos días, reiniciar el servicio es tratar el síntoma, no la causa. Reiniciar Docker corrige la corrupción del puente de red y el estado obsoleto de los endpoints, pero no ayuda con pools agotados ni con un puerto del host genuinamente ocupado — en esos casos necesitás resolver la causa raíz (limpiar redes, liberar el puerto) o vas a estar reiniciando el servicio indefinidamente.

Si administrás un servidor Debian con un panel de control (Plesk, cPanel, etc.) que gestiona su propio firewall, vale la pena investigar si ese panel está flusheando las reglas de iptables en cada aplicación de cambios. Ahí es donde conviene configurar excepciones o scripts de post-arranque que reinserten las cadenas de Docker automáticamente.

Resumen práctico según tu perfil

  • Si estás en desarrollo local (Mac/Windows/Docker Desktop): el 90% de los casos es un puerto ocupado. Corré lsof -i :PUERTO o cambiá el mapeo de puertos.
  • Si administrás un VPS Debian/Ubuntu con Docker en producción: sospechá primero de iptables/nftables, especialmente si usás UFW, firewalld, o un panel de control que también gestiona el firewall. systemctl restart docker resuelve la mayoría de los casos.
  • Si corrés Docker en un pipeline de CI/CD: el sospechoso número uno es agotamiento de pools de red por redes que nunca se eliminan. Agregá docker network prune -f a tu limpieza post-build.

En conclusión, "Driver failed programming external connectivity" no es un solo error: es un síntoma de red que puede venir de un puerto ocupado, de un firewall que rompió las cadenas de Docker, o de un estado de red obsoleto. La clave está en leer la línea completa del mensaje —ahí está la pista real— y aplicar el diagnóstico correspondiente en vez de reiniciar servicios a ciegas.

¿Tu error tenía un mensaje distinto a los de esta tabla? Contámelo en los comentarios y lo sumamos a la guía.

Comentarios

Entradas populares de este blog

El USB-C de la IA: cómo MCP pasó de protocolo de Anthropic a infraestructura de toda la industria en 16 meses

El vibe coding: ¿el fin de los programadores o el inicio de una nueva era?

Claude encontró un bug de 29 años que nadie había visto — y ahora los gobiernos quieren controlar la IA que puede hacer esto