ERROR 2002: Can't connect
El ERROR 2002 es uno de los primeros obstáculos que encuentra casi cualquier persona que instala MySQL o que despliega una aplicación en un servidor nuevo. Aparece cuando el cliente intenta conectarse al servidor MySQL de la propia máquina y no consigue establecer la conexión. A diferencia de los errores de permisos, aquí ni siquiera se llega a comprobar el usuario ni la contraseña: el cliente no encuentra a nadie al otro lado. La buena noticia es que sus causas son pocas y bien conocidas, y con un diagnóstico ordenado se resuelve en pocos minutos.
El mensaje de error
El mensaje completo que muestra el cliente mysql en Linux suele tener este aspecto. El texto incluye la ruta del socket que el cliente ha intentado usar y, entre paréntesis, un código del sistema operativo que da una pista importante sobre la causa:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
El número final es el código errno del sistema. El valor 2 significa "No such file or directory": el archivo del socket no existe en esa ruta, normalmente porque el servidor no está en marcha o porque lo creó en otro lugar. El valor 111 significa "Connection refused": el archivo existe, pero ningún proceso está escuchando en él, algo típico cuando el servidor se ha detenido de forma brusca y dejó el socket huérfano. También puede aparecer 13, "Permission denied", cuando el usuario del sistema que ejecuta el cliente no tiene permiso para acceder al directorio del socket.
En macOS con Homebrew la ruta cambia, porque el servidor crea el socket en el directorio temporal del sistema:
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
Desde aplicaciones el error llega con el mismo código envuelto en la excepción del lenguaje. En PHP con PDO, por ejemplo, verás SQLSTATE[HY000] [2002] No such file or directory, y en Laravel ese mismo texto dentro de una QueryException.
Qué significa realmente
Para entender este error hay que saber que el cliente de MySQL tiene dos formas de conectarse a un servidor local. La primera es a través de TCP/IP, igual que se conectaría a un servidor remoto, usando una dirección IP y un puerto (por defecto el 3306). La segunda es mediante un socket Unix, un archivo especial del sistema de archivos que permite comunicar dos procesos de la misma máquina sin pasar por la pila de red, lo que resulta algo más rápido y seguro.
La clave está en que, en sistemas tipo Unix, cuando indicas localhost como host (o no indicas ningún host, que equivale a lo mismo), el cliente de MySQL no usa TCP: usa el socket. Por eso el mensaje habla de "local MySQL server through socket". Si en cambio indicas 127.0.0.1, el cliente usa TCP aunque el destino sea la misma máquina. Esta distinción explica muchos casos desconcertantes en los que mysql -h 127.0.0.1 funciona y mysql -h localhost falla, o al revés.
El error equivalente cuando se usa TCP es el ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1:3306'. Ambos indican que no hay un servidor disponible donde el cliente lo busca, pero el 2002 se refiere al socket y el 2003 a una dirección de red. Si ves el 2003, el problema está en la red, el puerto, el firewall o la opción bind-address, y no en el archivo del socket.
Causas más frecuentes
La causa más habitual con diferencia es la más simple: el servidor MySQL no está en ejecución. Puede que nunca se haya arrancado tras la instalación, que se haya detenido tras un reinicio de la máquina porque el servicio no está habilitado, o que se haya caído por falta de memoria. Si no hay servidor, no hay socket, y el cliente responde con el código (2).
La segunda causa es que el cliente y el servidor no están de acuerdo sobre la ruta del socket. El servidor crea el socket donde indica su variable socket, y el cliente lo busca donde indica su propia configuración o la ruta compilada por defecto. Esto ocurre cuando se mezclan paquetes de distintas procedencias (por ejemplo, el cliente de la distribución y el servidor de los repositorios oficiales de Oracle), cuando se edita la sección [mysqld] del archivo de configuración sin actualizar la sección [client], o cuando un lenguaje como PHP tiene su propia ruta configurada en pdo_mysql.default_socket.
Otra causa frecuente es que el servidor intentó arrancar pero falló. Un error de sintaxis en my.cnf, una opción que ya no existe en MySQL 8.0 u 8.4, un disco lleno, un directorio de datos con permisos incorrectos o un puerto ya ocupado por otra instancia hacen que mysqld se detenga al instante. El servicio aparece como fallido y, de nuevo, no hay socket.
Los permisos también pueden intervenir. El directorio que contiene el socket (en Debian y Ubuntu, /var/run/mysqld) debe existir y pertenecer al usuario mysql. Como /var/run es un sistema de archivos temporal que se vacía al reiniciar, si ese directorio desaparece y nada lo recrea, el servidor no puede crear el socket.
Por último, están los entornos con contenedores y subsistemas. Si MySQL corre dentro de un contenedor de Docker y te conectas desde la máquina anfitriona con localhost, el cliente busca un socket en el sistema de archivos del anfitrión, donde no existe, porque el socket vive dentro del contenedor. Algo parecido ocurre en WSL cuando el servidor está instalado en Windows y el cliente en Linux, o cuando el servicio de MySQL dentro de WSL no se arranca automáticamente al abrir la terminal.
Diagnóstico paso a paso
Antes de cambiar nada conviene averiguar cuál de las causas anteriores es la tuya. El primer paso es comprobar si el servidor está en marcha. En distribuciones con systemd el servicio se llama mysql en Debian y Ubuntu, y mysqld en RHEL, Rocky Linux o Fedora:
# Debian / Ubuntu
sudo systemctl status mysql
# RHEL / Rocky / AlmaLinux / Fedora
sudo systemctl status mysqldSi el estado es active (running), el servidor funciona y el problema está en la ruta o en los permisos. Si aparece inactive (dead) o failed, has encontrado la causa. También puedes buscar el proceso directamente, lo que es útil en sistemas sin systemd:
ps aux | grep mysqldCuando el servicio ha fallado, las últimas líneas del registro de systemd suelen explicar el motivo. Este comando muestra las entradas más recientes del servicio:
sudo journalctl -u mysql -n 50 --no-pagerEl registro de errores de MySQL da todavía más detalle. En Debian y Ubuntu está en /var/log/mysql/error.log, y en RHEL y derivados en /var/log/mysqld.log. Mensajes como unknown variable, No space left on device o Permission denied señalan directamente la causa:
sudo tail -n 50 /var/log/mysql/error.logSi el servidor está en marcha, el siguiente paso es averiguar dónde ha creado el socket. Si puedes conectarte de algún modo, por ejemplo por TCP, la variable socket te da la ruta exacta:
mysql -u root -p -h 127.0.0.1 -e "SHOW VARIABLES LIKE 'socket';"+---------------+-----------------------------+
| Variable_name | Value |
+---------------+-----------------------------+
| socket | /var/run/mysqld/mysqld.sock |
+---------------+-----------------------------+
Si no puedes conectarte, busca el valor en los archivos de configuración o comprueba qué archivos de socket existen. El comando mysqladmin también sirve como prueba rápida, porque intenta conectarse igual que el cliente:
ls -l /var/run/mysqld/
mysqladmin -u root -p statusSoluciones
Una vez identificada la causa, la solución suele ser directa. Las siguientes subsecciones cubren los casos más comunes en el orden en que conviene probarlos.
Arrancar el servidor
Si el diagnóstico mostró que el servidor está detenido, basta con arrancarlo y habilitarlo para que se inicie automáticamente al encender la máquina. El artículo sobre cómo iniciar MySQL explica en detalle las opciones de cada sistema:
# Debian / Ubuntu
sudo systemctl start mysql
sudo systemctl enable mysql
# RHEL / Rocky / AlmaLinux / Fedora
sudo systemctl start mysqld
sudo systemctl enable mysqld
# macOS con Homebrew
brew services start mysqlSi el servicio vuelve a fallar al arrancar, no insistas: revisa el registro de errores como se indicó en el diagnóstico, corrige la causa (una línea incorrecta en la configuración, espacio en disco, permisos del directorio de datos) y vuelve a intentarlo. Después de cambiar la configuración conviene reiniciar MySQL para que los cambios surtan efecto.
Forzar la conexión por TCP
Cuando el servidor funciona pero el cliente no encuentra el socket, la forma más rápida de conectarte es evitar el socket por completo. Usar 127.0.0.1 en lugar de localhost obliga al cliente a conectarse por TCP. También puedes indicarlo explícitamente con --protocol=TCP:
mysql -u root -p -h 127.0.0.1 -P 3306
mysql -u root -p --protocol=TCPEsta solución es especialmente útil en aplicaciones. En Laravel, por ejemplo, cambiar DB_HOST=localhost por DB_HOST=127.0.0.1 en el archivo .env hace que PDO use TCP y el error desaparece. Ten en cuenta que MySQL trata localhost y 127.0.0.1 como hosts distintos para los permisos, así que el usuario debe tener acceso desde 127.0.0.1 o desde %. Si no lo tiene, pasarás a ver el ERROR 1045 Access denied.
Indicar la ruta correcta del socket
Si prefieres seguir usando el socket, indica al cliente la ruta real que obtuviste en el diagnóstico. Puedes hacerlo en cada conexión con la opción --socket:
mysql -u root -p --socket=/var/lib/mysql/mysql.sockPara no tener que escribirla cada vez, añade la ruta a la sección [client] del archivo de configuración, de modo que coincida con la de la sección [mysqld]. El artículo sobre el archivo de configuración explica dónde se encuentra este archivo en cada sistema y en qué orden se leen:
[mysqld]
socket=/var/run/mysqld/mysqld.sock
[client]
socket=/var/run/mysqld/mysqld.sockEn PHP, si el problema solo aparece desde la aplicación, revisa también las directivas pdo_mysql.default_socket y mysqli.default_socket del archivo php.ini, que deben apuntar a la misma ruta.
Recrear el directorio del socket
Cuando el registro de errores indica que el servidor no puede crear el socket por un problema de permisos o porque el directorio no existe, hay que recrearlo con el propietario correcto. En Debian y Ubuntu serían estos comandos, seguidos de un reinicio del servicio:
sudo mkdir -p /var/run/mysqld
sudo chown mysql:mysql /var/run/mysqld
sudo systemctl restart mysqlSi el socket existe pero el código de error era (111), se trata de un socket huérfano de una ejecución anterior. Reiniciar el servicio normalmente lo sustituye por uno nuevo y funcional.
Docker y WSL
Con Docker, el socket del servidor está dentro del contenedor, así que desde el anfitrión hay que conectarse siempre por TCP al puerto publicado. Si arrancaste el contenedor con -p 3306:3306, esta es la forma correcta de conectarse:
mysql -u root -p -h 127.0.0.1 -P 3306Si lo que quieres es usar el cliente que viene dentro de la propia imagen, ejecútalo en el contenedor, donde localhost sí apunta al socket correcto:
docker exec -it nombre_contenedor mysql -u root -pEn WSL, recuerda que los servicios no siempre arrancan solos al abrir la terminal. Comprueba el estado con sudo service mysql status y arráncalo con sudo service mysql start. Si el servidor está instalado en Windows y el cliente en WSL, no compartirán socket: conéctate por TCP a la dirección de Windows.
Cómo evitarlo
La mejor prevención es tener el servicio habilitado para que arranque con el sistema y vigilar que se mantiene en marcha. Un servidor que se cae por falta de memoria volverá a caerse, así que si el registro de errores muestra que el proceso fue terminado por el sistema, ajusta la memoria asignada a InnoDB o amplía los recursos de la máquina.
También ayuda ser coherente con la configuración de conexión. Si tus aplicaciones se conectan siempre con 127.0.0.1 por TCP, o siempre por socket con una ruta explícita, evitarás depender de rutas compiladas por defecto que cambian según el paquete o la versión. Para entender todas las formas de conectarte y sus opciones, consulta el artículo sobre conectarse al servidor MySQL.
Por último, instala el cliente y el servidor desde la misma fuente. Mezclar el paquete de la distribución con los repositorios oficiales de MySQL, o una instalación de Homebrew con otra descargada manualmente, es la receta perfecta para que cada uno busque el socket en un sitio distinto.
Resumen
El ERROR 2002 indica que el cliente intentó conectarse a un servidor local a través del socket Unix y no lo encontró. En la mayoría de los casos el servidor está detenido o no pudo arrancar, y la solución pasa por comprobar su estado con systemctl, leer el registro de errores y arrancarlo. Cuando el servidor funciona, el problema suele ser una ruta de socket distinta entre cliente y servidor, que se resuelve indicando la ruta correcta o conectándose por TCP con 127.0.0.1.
Si tras aplicar estas soluciones el mensaje cambia a ERROR 2003, el problema ya no es el socket sino la conexión TCP: revisa el puerto, el firewall y la opción bind-address. Y si el mensaje pasa a ser ERROR 1045, enhorabuena: el cliente ya llega al servidor, y lo que falla ahora es el usuario o la contraseña.
Escrito por Eduardo Lázaro
