The Error
You try to connect to MySQL from your app or a remote host and get slapped with this:
ERROR 1129 (HY000): Host '192.168.1.10' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
MySQL blocked your host because it saw too many failed connection attempts in a row. Once a host exceeds the max_connect_errors threshold, MySQL blacklists it. It won't let that IP back in until you manually clear the block โ or restart the server.
Why This Happens
Each time a client connects but fails before authentication completes โ due to a network drop, an aborted handshake, or a misconfigured client โ MySQL ticks up an internal counter for that host. Hit the max_connect_errors limit (default: 100), and MySQL shuts the door.
Common culprits:
- App restarts or crashes mid-connection, leaving half-open TCP sockets
- Network instability between the app server and the database
- Connection pool set to reconnect too aggressively on failure
- A firewall or load balancer cutting connections before MySQL finishes the handshake
- Outdated MySQL client libraries with broken SSL/TLS negotiation
Step 1 โ Unblock the Host Right Now
Before anything else, restore access by flushing the host cache. Three ways to do it:
Option A: Using mysqladmin
mysqladmin -u root -p flush-hosts
Option B: From inside a MySQL session
-- Connect as root from localhost (which isn't blocked)
mysql -u root -p
-- Then run:
FLUSH HOSTS;
Option C: MySQL 8.0.26+ only โ truncate the performance_schema table
TRUNCATE TABLE performance_schema.host_cache;
All three reset the error counter for every blocked host. Run any one of them, then retry your connection โ it should go through immediately.
Step 2 โ Find Out Why Connections Were Failing
Flushing hosts buys you time. Without fixing the root cause, the block will return โ sometimes within minutes on a busy app server. Start with the MySQL error log:
# Default location on Ubuntu/Debian
tail -100 /var/log/mysql/error.log
# On CentOS/RHEL
tail -100 /var/log/mysqld.log
# Not sure where your log is?
SHOW VARIABLES LIKE 'log_error';
Scan for Aborted connection, Got an error reading communication packets, or Got timeout reading communication packets. Those lines point directly at the failing connections.
Then pull the aborted connection counters:
SHOW GLOBAL STATUS LIKE 'Aborted_connects';
SHOW GLOBAL STATUS LIKE 'Aborted_clients';
- Aborted_connects โ failed before authentication. This is exactly what triggers ERROR 1129.
- Aborted_clients โ connected fine but disconnected badly. Less urgent, but worth watching.
Step 3 โ Raise max_connect_errors (Stopgap Measure)
Got frequent but harmless interruptions โ flaky VPN, aggressive Kubernetes liveness probes, or a health check that can't authenticate? You can raise the threshold so MySQL doesn't block so fast.
Set it live without restarting:
SET GLOBAL max_connect_errors = 1000000;
Make it stick in my.cnf / my.ini:
[mysqld]
max_connect_errors = 1000000
Then restart MySQL:
# Ubuntu/Debian
sudo systemctl restart mysql
# CentOS/RHEL
sudo systemctl restart mysqld
Setting this very high โ or to 0 in MySQL 8.0.36+ to disable blocking entirely โ is fine on internal networks where you trust all hosts. On anything public-facing, keep it lower.
Step 4 โ Fix the Actual Connection Problem
Connection pool reconnecting too aggressively?
Many frameworks hammer MySQL on startup with rapid-fire reconnect attempts. Add a pre-ping check and a recycle interval. Here's what that looks like in Python SQLAlchemy:
engine = create_engine(
DATABASE_URL,
pool_pre_ping=True, # Validate connections before using them
pool_recycle=3600, # Drop and replace connections after 1 hour
connect_args={"connect_timeout": 10}
)
Reducing pool size during initial testing also helps isolate whether the pool itself is the problem.
Suspect a network or firewall issue?
Test raw TCP connectivity from the blocked host before touching any MySQL config:
telnet 192.168.1.100 3306
# or
nc -zv 192.168.1.100 3306
If the connection drops or just hangs, you're dealing with a network problem. MySQL config changes won't help.
SSL/TLS negotiation breaking things?
# Try connecting with SSL completely disabled
mysql -h 192.168.1.100 -u myuser -p --ssl-mode=DISABLED
Connects fine without SSL but fails normally? Update your client library or sort out the certificate config.
Verify the Fix
Once you've flushed hosts and addressed the root cause, confirm the IP is no longer blocked:
-- MySQL 8.0+ only
SELECT host, host_validated, sum_connect_errors, count_host_blocked_errors
FROM performance_schema.host_cache
WHERE host = '192.168.1.10';
sum_connect_errors should be at 0 or close to it. count_host_blocked_errors should not be climbing.
Quick sanity check from the command line:
mysql -h 192.168.1.100 -u myuser -p -e "SELECT 1;"
Returns 1? You're done.
Keep It From Happening Again
- Turn on
pool_pre_pingin your connection pool โ it validates connections before handing them out, so MySQL never sees a dead socket mid-handshake - Tune
wait_timeoutandinteractive_timeoutto match how long your app actually holds connections open - Watch
Aborted_connectsin your metrics stack โ a spike there is your early warning, usually minutes before ERROR 1129 hits - Put ProxySQL or HAProxy between your app and MySQL โ a proxy handles reconnection logic gracefully and won't blast MySQL with raw TCP retries during restarts
- Add
FLUSH HOSTSto your deployment scripts if app servers restart frequently during releases โ prevents a block from accumulating during a rolling deploy

