Fixing MySQL Error 1118: Row size too large (> 8126)

intermediate🗄️ MySQL2026-04-07| MySQL 5.6, 5.7, 8.0+, MariaDB, Linux/Windows/Docker environments using InnoDB engine.

Error Message

ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.
#mysql#row-size#innodb#schema#table-design

The ProblemYou’re midway through a database migration or adding a new feature to a user profile table when MySQL suddenly halts. This usually happens when a table grows too wide—perhaps you have dozens of VARCHAR columns or several large fixed-width fields. Even if your table is empty, MySQL calculates the maximum potential size of a row based on your schema definition. If that math doesn't add up, the process fails.

The specific error looks like this:

ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.

Why This HappensUnder the hood, InnoDB manages data in 16KB chunks called pages. To keep operations fast, MySQL requires that at least two rows fit into every page. Once you subtract the 126 bytes used for internal headers and system data, you are left with a hard limit of exactly 8,126 bytes per row.

Character sets make this limit easy to hit. If you use utf8mb4, MySQL reserves 4 bytes for every potential character. A table with just 10 VARCHAR(255) columns technically requests $10 \times 255 \times 4 = 10,200$ bytes. That is already 2,000 bytes over the limit, even before you add an ID or a timestamp.

Debug ProcessStart by identifying which row format your tables currently use. Run this command to see the metadata for your specific table:

SHOW TABLE STATUS LIKE 'your_table_name'\G

Next, check your global InnoDB environment variables. These settings dictate how MySQL handles row overflow and strictness:

SHOW VARIABLES LIKE 'innodb_strict_mode';
SHOW VARIABLES LIKE 'innodb_file_per_table';
SHOW VARIABLES LIKE 'innodb_default_row_format';

If innodb_strict_mode is ON, MySQL will block the creation of any table that might exceed the size limit. If your ROW_FORMAT is set to COMPACT or REDUNDANT, you are more likely to see this error because those older formats store more data directly inside the 8KB page.

Solutions### 1. Switch Row Format to DYNAMICChanging to the DYNAMIC row format is the most reliable fix. Think of it as moving bulky luggage to the cargo hold. While older formats try to stuff everything into the main row, DYNAMIC moves long variable-length data off-page. It leaves only a tiny 20-byte pointer behind, keeping your main row lean.

For a new table:

CREATE TABLE wide_table (
    id INT PRIMARY KEY,
    col1 VARCHAR(500),
    col2 VARCHAR(500),
    ...
) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;

For an existing table:

ALTER TABLE table_name ROW_FORMAT=DYNAMIC;

2. Convert VARCHAR to TEXT or BLOBIf specific columns are bloating your schema, try converting them to TEXT or BLOB. Unlike VARCHAR, these types are automatically eligible for off-row storage. This is especially helpful if you have 20 or 30 wide columns that don't need to be indexed.

-- Converting a wide VARCHAR to TEXT
ALTER TABLE table_name MODIFY column_name TEXT;

Keep in mind that TEXT columns can't have default values in older MySQL versions. Use them for large content blocks rather than short identifiers.

3. Disable InnoDB Strict Mode (Temporary Fix)You can force MySQL to accept a wide table by turning off strict mode. This is a "proceed at your own risk" workaround. The ALTER command will succeed, but you might still hit errors later when you try to INSERT actual data that exceeds the limit.

-- Disable for the current session only
SET SESSION innodb_strict_mode = 0;

-- Disable globally (requires SUPER privileges)
SET GLOBAL innodb_strict_mode = 0;

4. Optimize the Character SetUsing utf8mb4 is the gold standard for supporting emojis and international text, but it’s expensive in terms of row size. If a column only stores internal status codes or alphanumeric IDs, switching it to latin1 reduces its footprint from 4 bytes per character to just 1 byte.

Verification StepsAfter applying your changes, confirm that your table is stable and compliant:

  • Re-run your CREATE or ALTER command. It should finish without the 1118 error.- Double-check the active row format: SELECT table_name, row_format FROM information_schema.tables WHERE table_schema = 'your_database_name' AND table_name = 'your_table_name';- Run a stress test. Insert a record filled with the maximum allowed characters in every column to ensure no runtime crashes occur.## Lessons Learned- Normalize your data: Hitting the 8KB limit is often a warning sign. If your table has 100+ columns, consider splitting it into smaller, related tables using a 1:1 relationship.- Standardize on DYNAMIC: Modern MySQL (5.7.9+) defaults to DYNAMIC. If you've migrated from an old server, your tables might still be stuck in COMPACT mode.- Be precise with types: Stop using VARCHAR(255) as a default for everything. If a field only needs 20 characters, define it that way to keep your internal schema calculations small.

Related Error Notes