Someone on your team pastes a comment with a 😀 into a WordPress post, hits save, and instead of the post updating they get a wall of red text: WordPress database error: [Incorrect string value: '\xF0\x9F\x98\x80...' for column 'comment_content']. Or it happens on checkout — a customer's name has an emoji in it (more common than you'd think, especially with WhatsApp-native shoppers), and the order silently fails to save. This one isn't a plugin bug. It's a leftover from how MySQL used to handle "UTF-8" before it actually supported all of Unicode.

Symptom

You'll usually see one of these, depending on where the bad insert happened:

  • WordPress database error: [Incorrect string value: '\xF0\x9F\x98\x80' for column 'post_content' at row 1]
  • A WooCommerce order that just never appears, with nothing in the front-end but a spinning "Place Order" button
  • A REST API request (mobile app, headless frontend, Contact Form 7 submission) returning a 500 with a database error buried in the response body
  • Import scripts (WP All Import, CSV uploads, migration tools) stopping partway through with the same "Incorrect string value" message

The character in question is almost always outside the Basic Multilingual Plane — emoji, some rare CJK characters, mathematical symbols, or certain Indian regional script glyphs. Anything that needs 4 bytes to encode in UTF-8.

Cause: utf8 in MySQL Isn't Really UTF-8

This trips up a lot of people who know their charset is set to "utf8" and assume they're covered. Historically, MySQL's utf8 charset is a 3-byte-max implementation that only covers the Basic Multilingual Plane. It was named before the MySQL team realized true UTF-8 needs up to 4 bytes per character. By the time they fixed it, utf8 was already load-bearing in thousands of installs, so they shipped the real thing under a new name: utf8mb4.

WordPress switched its default table charset to utf8mb4 back in version 4.2 (2015), but that only applies to new installs and fresh table creates. If your site has been migrated, cloned, or restored from an older backup along the way — which describes most sites more than a few years old — there's a decent chance some or all of your tables, or even individual columns within a table, are still sitting on the old 3-byte utf8 charset. MySQL will happily let you create a table in utf8 even in 2026; it doesn't warn you.

When a 4-byte character hits a column that's still utf8, MySQL refuses the insert outright (in strict mode) or silently truncates/corrupts the string (in non-strict mode). Neither is what you want.

Step 1: Confirm the Charset Mismatch

Log into phpMyAdmin (cPanel → Databases → phpMyAdmin) or SSH in and check what your tables are actually running:

mysql -u your_db_user -p your_db_name -e "
SELECT TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'your_db_name'
ORDER BY TABLE_NAME;"

Look for anything with a collation starting in utf8_ (no "mb4") — those are the 3-byte holdouts. Common offenders: wp_posts, wp_comments, wp_postmeta, and on WooCommerce sites, wp_wc_order_addresses or custom order meta tables added by older WooCommerce versions or third-party plugins.

You should also check individual columns, since a table can report utf8mb4 overall while one or two text columns were altered separately and never got the memo:

mysql -u your_db_user -p your_db_name -e "
SELECT TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'your_db_name'
AND CHARACTER_SET_NAME IS NOT NULL
AND CHARACTER_SET_NAME != 'utf8mb4';"

Step 2: Back Up Before You Touch Anything

Converting charsets rewrites every row in the affected tables. Take a full database backup first — cPanel's Backup Wizard, or a manual dump:

mysqldump -u your_db_user -p --default-character-set=utf8 your_db_name > pre_utf8mb4_backup.sql

Download that file off the server too, not just onto the same disk. If something goes wrong mid-conversion, you want a copy that doesn't depend on the database you're currently mangling.

Step 3: Convert the Database, Tables, and Columns

There are three layers to update, and missing any one of them leaves you half-fixed. Start with the database default so anything new created later inherits the right charset:

ALTER DATABASE your_db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Then convert every table. This is the slow part on large sites — it locks and rewrites the table, so run it during low traffic:

ALTER TABLE wp_posts CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE wp_postmeta CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE wp_comments CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Repeat for every table information_schema flagged in Step 1. On a WordPress install with the default table set, that's usually around a dozen tables; WooCommerce and multisite add more.

Watch for the index length error. If you're still on an older MySQL/MariaDB version or an older InnoDB row format, converting can throw:

ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

This happens because utf8mb4 uses 4 bytes per character instead of 3, so indexed VARCHAR columns can exceed the old key-length limit. The fix is to confirm your table's row format is DYNAMIC or COMPRESSED (not the older COMPACT/REDUNDANT) and that innodb_large_prefix is on — both are default in MySQL 5.7+/MariaDB 10.2+, so this mostly bites sites running genuinely old database versions that are overdue for an upgrade anyway.

Use SHOW TABLE STATUS to check row format, or just run:

ALTER TABLE wp_options ROW_FORMAT=DYNAMIC;

before retrying the charset conversion on any table that throws that error.

Step 4: Fix wp-config.php

Make sure WordPress itself is asking for utf8mb4 on every connection, not just relying on the table default:

define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', '');

Leave DB_COLLATE empty — WordPress will pick the right collation automatically based on the MySQL version, which is safer than hardcoding one.

Step 5: Verify the Fix

Re-run the information_schema query from Step 1 and confirm nothing still shows plain utf8_*. Then do a real test: edit a post or add a comment containing an actual emoji, save it, and reload the page to make sure it round-trips correctly instead of showing a question mark or broken box character. For WooCommerce, place a test order with an emoji in the customer name or order note field.

What About Existing Corrupted Data?

If characters were already silently truncated or mangled before you fixed the charset (non-strict SQL mode lets bad inserts through as garbled text instead of rejecting them), the conversion won't retroactively repair that specific data — it only fixes how future writes are handled. You'd need to restore those specific rows from a backup taken before the corruption happened. This is one more reason to catch the charset mismatch early rather than after months of silent data loss.

Prevention

  • After any site migration, restore, or clone — including moving to a new SkyServer plan — re-run the information_schema charset check. Don't assume the destination inherited the right settings.
  • If you're setting up a brand-new database in cPanel → MySQL Databases, it'll default to utf8mb4 on current SkyServer hosting, but double-check if you're importing an old .sql dump that explicitly declares CHARSET=utf8 in its CREATE TABLE statements — the import will honor whatever the dump file says, overriding the server default.
  • Enable STRICT_TRANS_TABLES in your SQL mode so bad inserts fail loudly instead of silently corrupting data. It's more annoying in the short term but it turns silent data loss into a visible error you can actually fix.
  • If you use terminal" class="auto-link">WP-CLI, wp db check and wp db optimize won't catch charset mismatches directly, but a quick wp eval 'global $wpdb; var_dump($wpdb->charset);' confirms what WordPress thinks it's using versus what the tables actually have.

Frequently Asked Questions

Will converting to utf8mb4 break my existing content?

No, converting an already-valid utf8 table to utf8mb4 is a safe, lossless operation for existing correctly-stored data — you're widening the character set, not narrowing it. The risk only shows up in the reverse direction (mb4 to utf8) or when the row-format/key-length issue in Step 3 needs a table rebuild first.

Do I need to convert every table, or just the ones that hold post content?

Convert all of them, including wp_options, wp_usermeta, and any WooCommerce or plugin tables. Emoji and 4-byte characters can end up in unexpected places — usernames, custom field values, serialized option data — and a mismatch anywhere in that chain can throw the same error or cause serialization corruption.

My site uses utf8mb4_general_ci instead of utf8mb4_unicode_ci — is that a problem?

utf8mb4_general_ci is an older, slightly faster but less linguistically accurate collation. It won't cause the "Incorrect string value" error either way, since both collations support the full 4-byte character set. It only affects sorting and comparison edge cases (accented characters, some non-English sorting order). Not worth a conversion project on its own, but if you're already converting tables, standardizing on utf8mb4_unicode_ci (or utf8mb4_0900_ai_ci on MySQL 8) is a reasonable default.

Can I just strip emoji instead of fixing the database?

You can, with a plugin or a regex filter on form submissions, but that's treating the symptom. You'll still hit the same error the moment any other 4-byte character shows up — some regional scripts and rare symbols trigger it too, not just emoji — and you'll be permanently degrading what customers can type into your forms. Fixing the charset takes maybe 20 minutes on a typical WordPress database and removes the problem entirely.

Why didn't my hosting migration or restore fix this automatically?

A standard mysqldump/import preserves whatever charset was declared in the source database's CREATE TABLE statements. If the original site was built years ago on old defaults, that gets carried forward through every migration, backup, and restore indefinitely unless someone explicitly converts it. It's not something hosting migration tools change on your behalf, since doing so silently could alter data in ways a host shouldn't decide for you.