Fixing MySQL Error 1292: How to Handle '0000-00-00' Datetime Values

intermediate๐Ÿ—„๏ธ MySQL2026-04-13| MySQL 5.7+, MySQL 8.0+, MariaDB 10.2+, Linux (Ubuntu/CentOS), Windows (XAMPP/WAMP/Docker)

Error Message

ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'created_at' at row 1
#mysql#database-migration#sql-mode#backend-dev#error-1292

Why Your Migration Just FailedYou've likely hit this wall while migrating a legacy database to MySQL 5.7 or 8.0. It happens when an application tries to shove a 'dummy' date like 0000-00-00 into a DATETIME column. Older MySQL versions were lax, but modern versions enforce strict data integrity by default.

Common triggers for this error include:

  • Restoring an old .sql backup using the mysql < backup.sql command.- Running Laravel or Django migrations on a newly provisioned server.- Legacy PHP apps using 0000-00-00 as a placeholder instead of allowing NULL.``` ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'created_at' at row 1

## The Root Cause: Strict ModeModern MySQL environments use a setting called `sql_mode` to prevent data corruption. Two specific flags cause this datetime headache. `NO_ZERO_IN_DATE` stops dates like 2023-00-01, while `NO_ZERO_DATE` completely bans the `0000-00-00` value.
These flags are usually bundled inside `STRICT_TRANS_TABLES`. This mode ensures MySQL doesn't silently truncate invalid data. Instead, it stops the operation entirely to keep your data clean.
## Step 1: Inspect Your SQL ModeBefore changing any settings, see which modes are actually active. Run this command in your MySQL terminal:

SELECT @@sql_mode;


You will likely see a long string like `ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE...`. If those 'ZERO' flags are in the list, MySQL will reject your legacy date values every time.
## Step 2: The Quick Session FixSometimes you just need the migration to finish without rebooting the whole server. You can disable strict mode for your current connection only. This is perfect for one-time imports.

-- Wipe the mode for this session only SET SESSION sql_mode = '';

-- Or surgically remove the zero-date restrictions SET SESSION sql_mode = (SELECT REPLACE(@@sql_mode, 'NO_ZERO_DATE', '')); SET SESSION sql_mode = (SELECT REPLACE(@@sql_mode, 'NO_ZERO_IN_DATE', ''));


Once you run these commands, you can execute your `INSERT` or `UPDATE` statements in that same window without errors.
## Step 3: Making the Change PermanentTo keep this setting after a server restart, you must edit your configuration file. This is usually `my.cnf` on Linux or `my.ini` on Windows.
### On Linux (Ubuntu/Debian)- Open the file: `sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf`.- Locate the `[mysqld]` section.- Add or update the `sql_mode` line to exclude the zero-date flags:```
[mysqld]
sql_mode = "STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
```- Restart the service: `sudo systemctl restart mysql`.### On Windows (XAMPP/WAMP)- Open your XAMPP Control Panel and click "Config" next to MySQL.- Select `my.ini` and search for the `sql_mode` string.- Delete `NO_ZERO_IN_DATE` and `NO_ZERO_DATE` from the line.- Save the file and restart MySQL via the Control Panel.## Step 4: The "Right" Way (Data Sanitization)Disabling strict mode is a quick band-aid, but it isn't best practice. Modern applications should use `NULL` for unknown dates. This makes your database compatible with PostgreSQL and other engines that never allowed zero-dates.
First, modify your table to allow `NULL` values:

ALTER TABLE users MODIFY created_at DATETIME NULL;


Next, convert those invalid strings into actual `NULL` values. You may need to temporarily use the Session Fix from Step 2 to run this update:

SET SESSION sql_mode = ''; UPDATE users SET created_at = NULL WHERE created_at = '0000-00-00 00:00:00';


## Verification and Pro-TipsConfirm the fix by attempting a dummy insert. If `INSERT INTO your_table (created_at) VALUES ('0000-00-00 00:00:00');` works, you've successfully bypassed the restriction. Check your global status anytime with `SELECT @@GLOBAL.sql_mode;`.
When handling messy legacy data, it's easy to get lost in weird date formats. I often use the [Timestamp Converter on ToolCraft](https://toolcraft.app/en/tools/datetime/timestamp-converter) to verify if the integers in my logs are valid Unix timestamps. It helps catch whether a value is truly 0 or just a badly formatted string before you run a massive `UPDATE` query.

Related Error Notes