← Volver al Blog

"Bind: Address Already in Use" en Mac: cómo solucionarlo

El error "address already in use" significa que otro proceso ya ocupa el puerto. Qué lo causa en Mac, cómo encontrar y liberar el puerto, y por qué a veces TIME_WAIT lo deja bloqueado.

Levantas un servidor y muere de inmediato con bind: address already in use (o Address already in use, errno 48 en macOS). El mensaje es directo pero exacto: algo ya ocupa el puerto al que intentas vincularte. Así lo encuentras y recuperas tu puerto.

Qué significa el error en realidad

Cuando un programa quiere escuchar en un puerto, llama a bind() sobre ese número de puerto. Si ya hay otro socket vinculado ahí, el sistema operativo lo rechaza con EADDRINUSE, “address already in use” (dirección ya en uso). En macOS es el errno 48 (en Linux es el 98, por si lo estás cruzando con otra fuente).

Hay dos causas distintas, y la solución cambia:

  1. Otro proceso ocupa realmente el puerto (el caso común).
  2. Una instancia anterior de tu propio programa dejó el puerto en TIME_WAIT (el caso engañoso).

Paso 1: Encuentra qué ocupa el puerto

Sustituye 3000 por tu puerto:

sudo lsof -i :3000 -n -P

Si algo lo ocupa, verás el proceso y el PID:

COMMAND   PID   USER   ...  NODE NAME
node     1421  aaron   ...  TCP *:3000 (LISTEN)

Ahora sabes que node, PID 1421, ocupa el puerto 3000.

Paso 2: Libera el puerto

Si ese proceso es seguro de detener (un servidor de desarrollo viejo, un script olvidado), termínalo:

# Primero de forma elegante; le permite limpiar
kill 1421

# Si no se va, fuérzalo
kill -9 1421

O hazlo de una sola vez sin copiar el PID:

kill -9 $(lsof -ti :3000)

El flag -t hace que lsof muestre solo el PID, que se pasa directamente a kill. Consulta matar un proceso por puerto en Mac para saber cuándo preferir el SIGTERM elegante al SIGKILL forzado.

El caso TIME_WAIT: no hay nada en el puerto, pero sigue “en uso”

A veces lsof -i :3000 no devuelve nada y aun así obtienes “address already in use”. Esto suele ser TIME_WAIT: cuando una conexión TCP se cierra, el sistema operativo mantiene el socket reservado durante un breve enfriamiento (normalmente uno o dos minutos) para asegurarse de que ningún paquete rezagado de la conexión antigua se entregue por error a una nueva.

Puedes confirmarlo:

netstat -an | grep 3000

Si ves el puerto en TIME_WAIT en lugar de LISTEN, eso es lo que bloquea la revinculación. Dos formas de resolverlo:

  • Simplemente espera. El estado se limpia solo, normalmente en menos de dos minutos.
  • Haz que tu servidor reutilice la dirección. La mayoría de los servidores pueden activar la opción de socket SO_REUSEADDR, que permite a un socket nuevo vincularse a un puerto aún en TIME_WAIT. En Node está activa por defecto; en muchos frameworks hay un flag de “reutilizar dirección”. Esta es la solución correcta a largo plazo para servidores que reinicias constantemente.

Paso 3: O simplemente cambia tu puerto

Si no puedes detener con seguridad lo que ocupa el puerto, apunta tu app a otro sitio:

# Ejemplos
PORT=3001 npm start
flask run --port 5001

Mover tu app suele ser más seguro que matar un proceso que no puedes identificar al instante, sobre todo si el puerto pertenece a un servicio del sistema.

Por qué sigue pasando

La causa raíz siempre es la misma: solo un programa puede escuchar en un puerto a la vez. Servidores caídos que no liberaron su puerto, dos herramientas que vienen por defecto en el 3000, un depurador aún conectado en segundo plano: todo produce el mismo error. La habilidad está en identificar rápido qué ocupa el puerto, que es justo lo que hacen los pasos anteriores.

Encuentra al culpable al instante

Portie muestra cada proceso que ocupa un puerto en tu Mac en una sola tabla en vivo, así que cuando te topas con “address already in use”, ves exactamente qué hay en ese puerto sin escribir un comando lsof, y lo terminas con un clic.

El monitoreo local es gratuito. El desbloqueo de $8.99 (pago único) agrega la terminación de procesos con un clic (elegante o forzada) y el escaneo remoto de puertos. Descarga Portie y no vuelvas a descifrar el errno 48 a mano.

Prueba Portie gratis

Ve cada puerto abierto en tu Mac, qué app lo usa y cierra procesos desde la lista.

Descargar gratis