Incident Response

MySQL "Got a packet bigger than max_allowed_packet": How to Fix It

A restore stops at line 4127, or an upload of a large file kills the connection. MySQL is enforcing a size limit, and there are two of them, one on each end of the connection. Here is how to find which one you hit and how far to raise it.

· 11 min read · AG Data Team

The MySQL error "Got a packet bigger than 'max_allowed_packet' bytes" means one side of the connection received a single message larger than it is allowed to accept. That message can be one SQL statement, one result row, or one binary log event on its way to a replica. MySQL refuses it and closes the connection. The fix is almost always to raise max_allowed_packet, but on the right side, and not blindly to the maximum.

The classic case is a restore:

ERROR 1153 (08S01) at line 4127: Got a packet bigger than 'max_allowed_packet' bytes

Error 1153 (ER_NET_PACKET_TOO_LARGE, SQLSTATE 08S01) comes from the server. The client library has its own version, error 2020 "Got packet bigger than 'max_allowed_packet' bytes" (server errors, client errors). Because the connection is closed, some clients report only "Lost connection to MySQL server during query" or the well-known MySQL server has gone away, which hides the real cause.

Two limits, one on each end

This is the part that confuses people. According to the MySQL manual, the client and the server each have their own max_allowed_packet, and to move big packets you must raise both. The defaults are different:

So the direction matters. Sending a 40MB statement from the mysql client to a server set to 64MB still fails, because the client is at 16MB. Reading works the same way in reverse: the server does not send more than its global max_allowed_packet, whatever the client allows.

Step 1: find out which side refused

-- server side: global value (what new connections get)
SELECT @@GLOBAL.max_allowed_packet / 1024 / 1024 AS server_mb;

-- your current session (read-only, fixed at connect time)
SELECT @@SESSION.max_allowed_packet / 1024 / 1024 AS session_mb;

-- how big is the biggest value you actually store?
SELECT MAX(LENGTH(payload)) / 1024 / 1024 AS biggest_mb FROM documents;

Compare those numbers with the size of what you are sending. If the error is 1153 from the server, the server limit is too small. If it is 2020 or appears in a client tool, look at the client's option file or connection string. Also check where the big packet comes from. Typical sources in our experience:

Step 2: raise the server limit the right way

max_allowed_packet is dynamic, but with one catch: the session value is read-only and is set when the client connects. Changing the global value helps new connections only. Your application pool keeps the old value until it reconnects.

-- MySQL 8.0+: change now and keep it after restart
SET PERSIST max_allowed_packet = 268435456;   -- 256MB

# or in my.cnf
[mysqld]
max_allowed_packet = 256M

Is raising it safe? The manual says yes: the extra memory is allocated only when needed. Each connection's buffer starts at net_buffer_length (16KB by default) and grows up to max_allowed_packet only for a big statement or row. The small default is a precaution against broken packets and against running out of memory by accident. In practice we pick a value with headroom over the largest real value, such as 256MB, rather than 1GB everywhere. A thousand connections each sending a 1GB packet at once is a memory problem no setting will save you from.

Do not forget the client. After raising the server limit, a restore with the mysql client can still fail at 16MB. Pass --max_allowed_packet to the client too, or set it in the [mysql] or [client] section of the option file.

Restoring dumps

# restoring a dump: the mysql client defaults to 16MB, raise it too
mysql --max_allowed_packet=256M appdb  < dump.sql

Two notes from the mysqldump documentation. First, its --network-timeout option is on by default and raises mysqldump's own packet limit to the maximum while dumping, so a dump usually goes through and the problem shows up on restore. Second, the client's setting cannot beat the server: a single packet can never exceed the server's max_allowed_packet, whatever mysqldump is set to. With --extended-insert (part of the default --opt), mysqldump builds multi-row INSERTs up to --net-buffer-length bytes (16KB by default). So a statement in a dump is only huge when a single row is huge, and then raising the limits is the only fix. This is exactly the kind of failure that a regular restore test catches before an incident does.

Replication

Large row events can break replication as well. On the replica, the relevant setting is replica_max_allowed_packet, which defaults to 1GB and applies to the receiver and applier threads (replica options). The manual notes that a source can write events longer than its own max_allowed_packet once the event header is added, so the replica value must be larger than the source's. If the source refuses to send an event, the replica's error contains the text "log event entry exceeded max_allowed_packet; Increase max_allowed_packet on source" (rpl_binlog_sender.cc). If the replica refuses it, the log says "Log entry on source is longer than replica_max_allowed_packet". The CLONE plugin has its own check too and tells you the minimum value it needs.

When raising the limit is the wrong fix

If the big packet comes from application code, the better fix is often in the code. Batch bulk inserts by a few thousand rows. Replace a giant IN list with a temporary table and a join. Consider storing multi-hundred-megabyte files in object storage and keeping only a reference in MySQL. A limit raised to 1GB just to make one bad query pass will let the next bad query through as well.

Key takeaways

MySQL max_allowed_packet Restore Troubleshooting
Work with us

Restore or migration stuck on MySQL errors?

We restore and migrate MySQL databases of any size, fix the limits that break large imports and replication, and make sure the next restore works before you need it.

Get in touch More from the blog