MySQL does not allow default values on BLOB, TEXT, GEOMETRY, or JSON columns due to how these types allocate memory. Remove the DEFAULT clause or use expression syntax (MySQL 8.0.13+) to fix this error.
This error occurs because MySQL has a fundamental limitation on BLOB, TEXT, GEOMETRY, and JSON data types—they cannot have default values assigned to them directly. This restriction exists because each BLOB, TEXT, GEOMETRY, or JSON value is represented internally by a separately allocated object, unlike other data types that have storage allocated once per column when the table is opened. When you attempt to create or alter a table with a DEFAULT clause on these column types, MySQL raises ERROR 1101 to prevent an invalid schema definition. The error is intentional and by design to maintain database integrity.
The simplest solution is to remove the DEFAULT clause entirely. BLOB, TEXT, JSON, and GEOMETRY columns will automatically accept NULL unless you explicitly mark them as NOT NULL.
Replace:
CREATE TABLE users (
id INT PRIMARY KEY,
profile TEXT NOT NULL DEFAULT 'N/A'
);With:
CREATE TABLE users (
id INT PRIMARY KEY,
profile TEXT NOT NULL
);If your application requires a value, handle the default in your application code or use a trigger instead.
If you are using MySQL 8.0.13 or later, you can assign default values to BLOB, TEXT, GEOMETRY, and JSON columns, but only if the default is written as an expression (even if it's a literal value).
For JSON columns, use expression syntax:
CREATE TABLE settings (
id INT PRIMARY KEY,
config JSON DEFAULT (JSON_OBJECT())
);For TEXT columns with literal defaults, wrap in parentheses:
CREATE TABLE posts (
id INT PRIMARY KEY,
content TEXT DEFAULT ('')
);For empty arrays in JSON:
CREATE TABLE items (
id INT PRIMARY KEY,
tags JSON DEFAULT (JSON_ARRAY())
);The key difference is the parentheses around the expression.
If you need automatic value initialization for LOB columns and you're on MySQL < 8.0.13 or need more control, create a BEFORE INSERT trigger:
CREATE TABLE documents (
id INT PRIMARY KEY AUTO_INCREMENT,
content LONGTEXT,
metadata JSON
);
DELIMITER //
CREATE TRIGGER set_defaults_before_insert
BEFORE INSERT ON documents
FOR EACH ROW
BEGIN
IF NEW.content IS NULL THEN
SET NEW.content = 'Default document content';
END IF;
IF NEW.metadata IS NULL THEN
SET NEW.metadata = JSON_OBJECT('created', NOW());
END IF;
END //
DELIMITER ;This approach gives you more flexibility and works across all MySQL versions.
If your data is relatively small (under 65,535 bytes), consider using VARCHAR instead of TEXT or VARBINARY instead of BLOB. These types support DEFAULT values:
-- Instead of TEXT with DEFAULT
CREATE TABLE posts (
id INT PRIMARY KEY,
excerpt VARCHAR(500) DEFAULT 'No excerpt provided'
);
-- Instead of BLOB with DEFAULT
CREATE TABLE files (
id INT PRIMARY KEY,
thumbnail VARBINARY(1000) DEFAULT 0x0000
);VARCHAR(n) allows up to n characters, and VARBINARY(n) allows up to n bytes. This is a viable solution if your content fits within these limits.
In STRICT modes (like STRICT_TRANS_TABLES or STRICT_ALL_TABLES), this error is raised immediately. While not recommended, you can temporarily check your SQL mode:
SELECT @@sql_mode;Do NOT disable STRICT_TRANS_TABLES permanently—it protects data integrity. Instead, fix your schema to comply with MySQL requirements.
Why does MySQL have this restriction?
BLOB, TEXT, GEOMETRY, and JSON columns have a fundamental architectural difference from standard data types. For standard columns (INT, VARCHAR, etc.), MySQL allocates storage once when the table is opened. For LOB (Large Object) types, each value requires separate memory allocation due to their variable size nature. This makes it impossible to pre-allocate a default value at table-definition time.
MariaDB difference: MariaDB 10.2.1+ supports literal default values for BLOB and TEXT columns natively, so if you migrate between MySQL and MariaDB, be aware of this compatibility difference.
ORM workarounds: If you use ORMs like Doctrine, Entity Framework, or Eloquent, configure them to not generate DEFAULT clauses for LOB column types. Many ORMs have options to skip defaults for BLOB/TEXT columns.
Generated columns: Starting with MySQL 5.7, you can use GENERATED columns to derive values from other columns, which can be helpful if you need computed defaults for JSON or TEXT columns.
ERROR 1064: You have an error in your SQL syntax
How to fix "ERROR 1064: You have an error in your SQL syntax" in MySQL
ERROR 1054: Unknown column in field list
Unknown column in field list
ER_WINDOW_RANGE_FRAME_NUMERIC_TYPE (3589): RANGE frame requires numeric ORDER BY expression
RANGE frame requires numeric ORDER BY expression in MySQL window functions
CR_ALREADY_CONNECTED (2058): Handle already connected
How to fix "CR_ALREADY_CONNECTED (2058): Handle already connected" in MySQL
ER_WINDOW_DUPLICATE_NAME (3591): Duplicate window name
How to fix ER_WINDOW_DUPLICATE_NAME (3591) in MySQL window functions