- Error number
- 1048
- SQLSTATE
23000- Symbol
ER_BAD_NULL_ERROR- Product
- MySQL Server
- Versions
- MySQL 5.7, 8.0 and 8.4
- Category
- Keys & Constraints
- Last reviewed
- 24 October 2026
On this page
What it means
Error 1048 means an INSERT or UPDATE explicitly put NULL into a column declared NOT NULL, so MySQL rejected the statement.
A NOT NULL column must always hold a value. When a statement supplies NULL for it, either as a literal, a bound parameter that is null, or a NULL coming out of a SELECT or a LEFT JOIN, MySQL returns 1048 and names the column. A DEFAULT on the column does not help: the default is used only when the column is left out of the INSERT or given the DEFAULT keyword, not when NULL is sent explicitly. That is why created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP still fails when the application passes NULL.
Leaving a NOT NULL column without a default out of the INSERT is a different error, 1364. Under strict mode (the MySQL 8.0 default) 1048 is always an error. Without strict mode a single-row INSERT still fails, but a multi-row INSERT, INSERT ... SELECT or UPDATE only warns and stores the type's implicit default (an empty string, 0 or a zero date), which silently corrupts data. Changing an existing column to NOT NULL while it holds NULLs gives error 1138 instead.
Common causes
- A form field or API value is missing, so the application binds NULL to a required column.
- The application sends NULL for a column that has a DEFAULT, expecting the default to apply (it does not).
- An INSERT ... SELECT or import copies NULLs from a staging table or a source column that allows them.
- An UPDATE with a LEFT JOIN or a subquery sets the column from a row that was not found, which yields NULL.
- An ORM maps an unset property to NULL and includes every column in the INSERT.
Diagnose it
Read-only These statements only read metadata (information_schema, performance_schema and SHOW statements) or your own data. They do not change data, privileges or configuration, so they are safe to run first.
Which columns are NOT NULL, and which have a default?
SELECT column_name, is_nullable, column_default, extra
FROM information_schema.columns
WHERE table_schema = DATABASE()
AND table_name = 'customers'
ORDER BY ordinal_position; is_nullable = NO marks the columns that reject NULL. A column with a column_default can simply be left out of the INSERT so the default applies.
Find the NULLs in the source before an INSERT ... SELECT or import
SELECT name, email
FROM staging_customers
WHERE name IS NULL OR email IS NULL; Every source row that would fail with 1048. Fix or exclude these rows, or decide on a real replacement value, before loading.
Check the session sql_mode
Useful when the same code errors on one server and only warns on another.
SELECT @@SESSION.sql_mode, @@GLOBAL.sql_mode; STRICT_TRANS_TABLES or STRICT_ALL_TABLES in the list means strict mode: NULLs are rejected rather than replaced by empty strings or zeros.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Supply a real value
Client or network sideValidate required fields in the application before the INSERT and return a clear message ("name is required"). This is the right fix whenever the column is NOT NULL because the business needs the value.
Leave the column out (or use DEFAULT) so its default applies
Changes dataIf the column has a DEFAULT, do not send NULL. Omit the column, or write the DEFAULT keyword. In an ORM, stop mapping unset properties to NULL for these columns.
INSERT INTO customers (name, email, created_at)
VALUES ('Ali', 'ali@example.com', DEFAULT);
Replace NULLs deliberately when copying data
Changes dataIn INSERT ... SELECT, choose what a missing value should become with COALESCE, or filter those rows out. Only use a placeholder when it is a meaningful value for the business; otherwise reject the rows.
INSERT INTO customers (name, email)
SELECT name, COALESCE(email, CONCAT('unknown+', name, '@example.com'))
FROM staging_customers
WHERE name IS NOT NULL;
Allow NULL if a missing value is genuinely valid
Changes schemaIf the data model allows "unknown" (for example a middle name or a phone number), make the column nullable. Do this as a design decision, not to silence the error.
Caution: Making a column nullable changes what every query and report must handle (NULL is not equal to anything, including another NULL). On a large table the ALTER may rebuild the table, so run it in a maintenance window.
ALTER TABLE customers MODIFY email VARCHAR(200) NULL;
Examples
Inserting NULL into a NOT NULL column
CREATE TABLE customers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(200) NOT NULL
);
INSERT INTO customers (name, email) VALUES (NULL, 'sara@example.com');
ERROR 1048 (23000): Column 'name' cannot be null
Reproduced on MySQL 8.0.46, 24 October 2026.
Sending NULL to a column that has a DEFAULT
CREATE TABLE customers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO customers (name, created_at) VALUES ('Ali', NULL); -- the default is not used for an explicit NULL
ERROR 1048 (23000): Column 'created_at' cannot be null
Reproduced on MySQL 8.0.46, 24 October 2026.
INSERT ... SELECT from a staging table that contains NULLs
CREATE TABLE customers (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(200) NOT NULL
);
CREATE TABLE staging_customers (name VARCHAR(100), email VARCHAR(200));
INSERT INTO staging_customers VALUES ('Omar', 'omar@example.com'), ('Lina', NULL);
INSERT INTO customers (name, email)
SELECT name, email FROM staging_customers;
ERROR 1048 (23000): Column 'email' cannot be null
Reproduced on MySQL 8.0.46, 24 October 2026.
An UPDATE through a LEFT JOIN that finds no match
CREATE TABLE customers (
id INT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(200) NOT NULL
);
CREATE TABLE email_updates (customer_id INT, new_email VARCHAR(200));
INSERT INTO customers VALUES (1, 'Sara', 'sara@example.com'), (2, 'Ali', 'ali@example.com');
INSERT INTO email_updates VALUES (1, 'sara@new.example.com');
UPDATE customers AS c
LEFT JOIN email_updates AS u ON u.customer_id = c.id
SET c.email = u.new_email; -- customer 2 has no update, so u.new_email is NULL
ERROR 1048 (23000): Column 'email' cannot be null
Reproduced on MySQL 8.0.46, 24 October 2026.
How to prevent it
Validate required values in the application and treat 1048 as a validation error, not a crash. Never send NULL for a column you want defaulted: omit it or use DEFAULT. In UPDATE statements, join with INNER JOIN (or add a WHERE clause) so rows without a match are not touched.
Keep strict mode on. Without it, multi-row inserts and updates replace NULL with empty strings, zeros or zero dates and only raise a warning, which is much harder to clean up later than an error you fix today.
Common questions
How do I fix MySQL error 1048?
Find where the NULL comes from (a missing form field, a NULL in the source query, or an unmatched LEFT JOIN) and supply a real value, omit the column so its DEFAULT applies, or make the column nullable if a missing value is genuinely valid.
My column has a DEFAULT, so why do I still get 1048?
Because the statement sent NULL explicitly. MySQL uses the default only when the column is left out of the INSERT or given the DEFAULT keyword. Remove the column from the INSERT, or stop your code from binding NULL to it.
What is the difference between error 1048 and error 1364?
1048 means NULL was supplied for a NOT NULL column. 1364 means a NOT NULL column without a default was left out of the INSERT altogether, so MySQL had no value to use.
Why does the same INSERT work on another server?
That server probably runs without strict mode, where a multi-row INSERT or INSERT ... SELECT stores an empty string or 0 and only raises a warning. That data is wrong rather than missing; fix the statement instead of turning strict mode off.
Learn more on CodeWithSQL
Official documentation
- MySQL 8.0 server error message reference
- Data type default values
- Server SQL modes (strict mode)
- Problems with NULL values
Last technically reviewed 24 October 2026; examples and diagnostics run on MySQL 8.0.46. Message templates checked against the server's error catalogue (perror) for that version.