NEW

Pulse 2025 Product Roundup: From Monitoring to AI-Native Control Plane

How to Fix MySQL Errors 2002 and 2003: Can't Connect to MySQL Server

MySQL raises two connection errors before any authentication occurs:

  • ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) — the socket file does not exist or is not accessible (errno 2 = ENOENT, errno 111 = ECONNREFUSED)
  • ERROR 2003 (HY000): Can't connect to MySQL server on 'hostname' (111) — TCP connection refused (errno 111 = ECONNREFUSED) or timed out (errno 110 = ETIMEDOUT)

Error 2002 is for Unix socket connections (local, --protocol=socket). Error 2003 is for TCP connections (--protocol=TCP, remote host, or 127.0.0.1).

Impact

These are pre-authentication errors — MySQL did not reject the credentials, it could not be reached at all. The application cannot open any connections. A 2002 or 2003 error at application startup prevents the service from starting. The same error during operation causes a full outage until the connection is restored.

Common Causes

Error 2002 (Socket)

  1. mysqld is not running — the socket file is only created when the daemon starts
  2. The socket file path in the client (/var/run/mysqld/mysqld.sock) does not match the path mysqld is using (socket in my.cnf)
  3. Permissions on the socket file or its directory prevent the OS user from connecting
  4. mysqld started but crashed before creating the socket

Error 2003 (TCP)

  1. mysqld is not running
  2. bind-address in my.cnf is set to 127.0.0.1 (localhost only), but the client is connecting from a different IP
  3. A firewall (iptables, security group, ufw) blocks port 3306
  4. mysqld is listening on a non-standard port and the client uses 3306
  5. The hostname in the connection string resolves to a different IP than expected (DNS issue)
  6. skip-networking is set in my.cnf, disabling TCP entirely

Troubleshooting and Resolution Steps

  1. Check whether mysqld is running:

    # systemd
    systemctl status mysql
    systemctl status mysqld
    
    # or directly
    pgrep -a mysqld
    ps aux | grep mysqld
    

    If not running, check the error log:

    journalctl -u mysql --since "1 hour ago"
    # or
    cat /var/log/mysql/error.log | tail -50
    
  2. Start mysqld if it is stopped:

    systemctl start mysql
    # or on older systems
    service mysql start
    
  3. Verify the socket file location:

    # What path is mysqld using?
    mysql -u root -p -e "SHOW VARIABLES LIKE 'socket'"
    # or from the configuration
    mysqld --verbose --help 2>/dev/null | grep "socket"
    
    # What socket path does the client default to?
    mysql --print-defaults | grep socket
    
    # Does the socket file exist?
    ls -la /var/run/mysqld/mysqld.sock
    

    If the paths differ, specify the socket explicitly:

    mysql -u root -p --socket=/path/to/actual.sock
    

    Or update the client's [client] section in my.cnf:

    [client]
    socket = /var/run/mysqld/mysqld.sock
    
  4. Check bind-address for TCP connection refusals:

    grep -r "bind.address\|bind-address\|skip.networking" /etc/mysql/ /etc/my.cnf 2>/dev/null
    
    SHOW VARIABLES LIKE 'bind_address';
    SHOW VARIABLES LIKE 'skip_networking';
    

    To allow remote connections, set bind-address = 0.0.0.0 (all interfaces) or a specific interface IP:

    [mysqld]
    bind-address = 0.0.0.0   # listen on all interfaces
    

    Then restart MySQL and ensure the user account grants access from the remote host (see error 1045).

  5. Verify which port and address mysqld is actually listening on:

    ss -tlnp | grep mysql
    netstat -tlnp | grep 3306
    # Look for: 0.0.0.0:3306 or 127.0.0.1:3306
    

    127.0.0.1:3306 means only local connections are accepted. 0.0.0.0:3306 means all interfaces.

  6. Test the TCP connection from the client machine:

    # Test reachability (no MySQL protocol — just TCP)
    nc -zv mysql-host 3306
    telnet mysql-host 3306
    # or
    curl -v telnet://mysql-host:3306
    
    # Expected: Connection to mysql-host 3306 port [tcp/*] succeeded!
    

    If this fails, the problem is the firewall or bind-address, not MySQL itself.

  7. Check and open the firewall:

    # UFW (Ubuntu)
    ufw allow from 10.0.1.0/24 to any port 3306
    ufw status
    
    # iptables
    iptables -I INPUT -s 10.0.1.0/24 -p tcp --dport 3306 -j ACCEPT
    
    # AWS Security Group: add inbound rule TCP port 3306 from the application's CIDR
    # GCP Firewall: gcloud compute firewall-rules create allow-mysql --allow tcp:3306
    
  8. For cloud databases (RDS, Aurora, Cloud SQL), check the security group / VPC:

    • The RDS instance's security group must have an inbound rule allowing TCP 3306 from the application's security group or CIDR.
    • The application and database must be in the same VPC, or VPC peering / VPN must be configured.
    • Check "Publicly accessible" setting — if No, the database is only reachable within the VPC.
  9. Connect to 127.0.0.1 instead of localhost when TCP is needed but socket is the default:

    # 'localhost' in MySQL clients means socket by default
    mysql -u root -p -h 127.0.0.1   # forces TCP
    mysql -u root -p -h localhost    # uses socket
    

    In connection strings:

    # Socket (localhost)
    mysql://root:pass@localhost/mydb
    
    # TCP (127.0.0.1)
    mysql://root:pass@127.0.0.1/mydb
    
  10. Remove skip-networking if it was accidentally set:

    [mysqld]
    # skip-networking   # comment out or remove
    

    Then restart MySQL. skip-networking disables all TCP connections and leaves only socket connections available.

  11. Check socket file permissions:

    ls -la /var/run/mysqld/
    # Expected: srwxrwxrwx 1 mysql mysql ... mysqld.sock
    # The socket must be writable by the connecting user or world-writable
    

    If the mysql CLI runs as root and the socket is only accessible to mysql user, run:

    chmod 777 /var/run/mysqld/mysqld.sock   # temporary fix
    # Better: run the client as the mysql OS user, or check my.cnf socket group
    

Additional Information

  • Error 2002 errno 2 (ENOENT) means the socket file does not exist — mysqld is not running or used a different socket path. Errno 111 (ECONNREFUSED) means the socket exists but nothing is listening on it.
  • Error 2003 errno 111 (ECONNREFUSED) means the TCP port is not open on the target host. Errno 110 (ETIMEDOUT) means the connection attempt timed out — typically a firewall drops the packets without sending a RST.
  • In containerized deployments (Docker, Kubernetes), MySQL and the application must be on the same Docker network or Kubernetes cluster. Referencing localhost from inside the application container points to the container itself, not to a MySQL container.
  • Amazon RDS Proxy, ProxySQL, and HAProxy each have their own listening address — check their configuration if the connection goes through a proxy.

Frequently Asked Questions

Q: MySQL is running but I still get error 2002 from the CLI. Why? A: The CLI is connecting via socket and the socket path in the client's my.cnf differs from where mysqld wrote the socket file. Run mysql --print-defaults | grep socket and mysql -e "SHOW VARIABLES LIKE 'socket'" to compare.

Q: The application connects fine on the same host but fails from another server. Why? A: bind-address = 127.0.0.1 restricts MySQL to local connections only. Set bind-address = 0.0.0.0 in my.cnf and restart, then verify the firewall allows port 3306 from the application server's IP.

Q: I changed bind-address but still get the error. Why? A: The change requires a MySQL restart. Verify with ss -tlnp | grep 3306 that MySQL is now listening on 0.0.0.0:3306 instead of 127.0.0.1:3306.

Q: After an OS reboot, MySQL fails to start because the socket file has wrong permissions. Why? A: Some installations write the socket to a tmpfs directory (/var/run) that is cleared on reboot. The mysql.service systemd unit or an init script recreates the directory on startup. Check systemctl status mysql for the startup error. Running systemd-tmpfiles --create or adjusting /etc/tmpfiles.d/mysql.conf fixes this.

Q: How do I connect to MySQL from a Docker container? A: Use Docker networking. If MySQL runs in a container named mysql-db on the default bridge network, connect to it using the container name as the hostname — but only if both containers are on the same user-defined network (docker network create). Or expose MySQL's port and connect via the host IP.

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.