Home › Database › MySQL 1364 Field Has No Default Value — Fix
Beginner 6 min · September 23, 2026

MySQL 1364 Field Has No Default Value — Fix

Fix MySQL error 1364 by naming every NOT NULL column in your INSERT or adding a DEFAULT — keep strict mode on, don't disable it..

N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Written from production experience, not tutorials.

Follow
✓ Production
production tested
September 24, 2026
last updated
1,942
articles · all by Naren
Before you start⏱ 9 min
  • ✓Basic SQL: CREATE TABLE, INSERT, and column constraints
  • ✓A MySQL 5.7+ server (or Docker) you can run queries against
  • ✓Familiarity with your app's ORM or query builder basics
 ● Production Incident 🔎 Debug Guide
⚡Quick Answer
  • Error 1364 means your INSERT skipped a NOT NULL column that has no DEFAULT, and STRICT_TRANS_TABLES refused to invent a value
  • Read SHOW CREATE TABLE first: any column marked NOT NULL without a DEFAULT clause must appear in your INSERT list
  • The durable fix is naming the column in the INSERT or adding a DEFAULT with ALTER TABLE — not disabling strict mode
  • ORMs often drop fields via fillable guards or serializers, so log the generated SQL to see what MySQL actually received
  • Dev and prod can differ: compare SELECT @@sql_mode on both, since lax dev settings hide 1364s that strict prod will throw
✦ Definition~90s read
What is MySQL 1364 No Default Value Fix?

MySQL error 1364 fires when an INSERT or UPDATE leaves a NOT NULL column with no DEFAULT unfilled while strict mode is active. The full text — Field 'x' doesn't have a default value — names the column MySQL couldn't fill. It's part of MySQL's strict-mode family (sql_mode flags like STRICT_TRANS_TABLES and STRICT_ALL_TABLES) that convert silent data coercion into hard errors.

★
Think of a MySQL table as a paper form where some boxes are marked required with no pre-printed answer.

Before strict mode became the default in 5.7, MySQL handled the same situation by writing implicit defaults — empty strings for VARCHAR, zeroes for INT, zero-dates for DATETIME — and issuing a warning most applications never read.

Strict mode exists because implicit defaults corrupt data quietly. An empty string in a plan column looks like a real value to every report, export, and billing job downstream; a zero in a price column can literally charge customers wrong. By refusing to guess, MySQL forces the application to state its intent: either supply the value in the query, declare a DEFAULT in the schema, or mark the column NULL.

Error 1364 is that refusal, and it's one of the most common errors teams meet after upgrades, migrations, or environment moves.

The error has four distinct causes that share one message: an INSERT that omits a required column, a schema whose NOT NULL column lacks a DEFAULT, an ORM or loader that drops the field before the SQL is built, and a sql_mode mismatch between environments. Each cause has its own fix — complete the INSERT, add a DEFAULT, whitelist the ORM field, or align sql_mode — and the wrong fix either masks the problem or rewrites a healthy schema.

What 1364 never means is that MySQL is broken; it means the server is enforcing a contract your write path violated.

Plain-English First

Think of a MySQL table as a paper form where some boxes are marked required with no pre-printed answer. Error 1364 is the clerk sliding your form back because you left a required box blank and there's no default to stamp in. MySQL's strict mode is that picky clerk — older clerks would scribble in an empty guess and file it, which is how junk data piled up. The fix is simple: fill in the box on your form, print a default answer on the form itself, or unmark the box as required.

Your deploy just went out, the logs look clean, and then support pings you: new signups are failing. The database error is terse — ERROR 1364 (HY000): Field 'plan' doesn't have a default value — and it names a column your code never touches. This error is MySQL's strict mode doing its job. When STRICT_TRANS_TABLES is on (the default since 5.7), MySQL refuses to invent values for NOT NULL columns you left out of an INSERT. Older servers would silently stuff in an empty string or zero and move on; modern MySQL throws 1364 instead. That's a gift, not a bug — silent implicit defaults corrupt data in ways you discover months later.

The trap is that 1364 rarely means what it first appears to say. Engineers read it as a schema problem and reach for ALTER TABLE, when the real culprit is often a query that forgot a column, an ORM that silently dropped a field, or a staging server whose sql_mode doesn't match production. Each cause has a different fix, and picking the wrong one either masks the error or rewrites a schema that was fine.

This guide walks through all five causes in order: reading the error line precisely, understanding strict mode, finding NOT NULL columns with no default, fixing the INSERT, choosing between a DEFAULT and relaxing sql_mode, and reconciling environment differences. You'll leave knowing exactly which fix your situation calls for.

Read the Error Line Before You Touch Anything

MySQL's error line is denser than it looks: ERROR 1364 (HY000): Field 'plan' doesn't have a default value. The number 1364 is the MySQL-specific error code you'll grep for in logs. HY000 is the generic SQLSTATE class — it tells you almost nothing beyond 'general error', so don't chase it. The quoted identifier is the column MySQL wanted a value for, and the table is conspicuously absent — you have to know which INSERT was running to map the column to its table.

The phrase 'doesn't have a default value' is precise: the column is NOT NULL and its definition carries no DEFAULT clause, so MySQL has nothing to fall back on. Under strict mode that's fatal for the statement. Without strict mode the same statement succeeds with a warning and an implicit default (empty string, zero, or a zero date), which is why veterans of older MySQL versions meet 1364 for the first time after an upgrade — their queries were always incomplete, and the server stopped covering for them.

Your first move is always SHOW CREATE TABLE for the target table. Read each column definition and mark every one that's NOT NULL with no DEFAULT. Then put your failing INSERT beside it and check off each required column. The gap between those two lists is your bug in nine cases out of ten. The tenth case — where the INSERT looks complete — means something between your code and MySQL rewrote the query, which is where ORM logging comes in.

SQL
1
2
3
4
5
6
7
8
9
-- Which table/columns can throw 1364? Inspect the definition first.
SHOW CREATE TABLE signups;

-- Confirm strict mode is what makes the omission fatal.
SELECT @@SESSION.sql_mode AS session_mode, @@GLOBAL.sql_mode AS global_mode;

-- Failing statement: 'plan' is NOT NULL with no DEFAULT.
INSERT INTO signups (email) VALUES ('a@example.com');
-- ERROR 1364 (HY000): Field 'plan' doesn't have a default value
📊 Production Insight
In production logs, 1364 almost always arrives without the query text — just the error and a timestamp. Correlate by time with slow-query or general logs, because guessing which INSERT failed from the column name alone wastes the first half hour.
🎯 Key Takeaway
Read the quoted column name, ignore the generic HY000 SQLSTATE, and diff SHOW CREATE TABLE against your INSERT list — the gap is the bug.

STRICT_TRANS_TABLES: The Tripwire Behind 1364

STRICT_TRANS_TABLES is a sql_mode flag that tells MySQL to reject bad writes instead of coercing them. With it on, a missing value for a NOT NULL column aborts the statement with 1364; an out-of-range value or a truncated string aborts with its own error. With it off, MySQL issues a warning, invents an implicit default, and writes a row you didn't ask for — empty strings where you expected data, zeroes where you expected measurements, zero-dates where you expected timestamps.

Since MySQL 5.7, strict mode is on by default in every official distribution and Docker image. That's why 1364 clusters around upgrades and new environments: code written against a lenient 5.6-era server, a Homebrew install with custom my.cnf, or a shared host that stripped strict flags suddenly faces a server that enforces the rules. The queries didn't change; the referee did.

This is working as designed, and the MySQL team has only tightened it since — 8.0 keeps strict defaults and adds even less tolerance for zero dates. Treat 1364 as a data-quality alarm, not an obstacle. Every implicit default it blocks is a corrupt row you don't have to clean up later. Teams that disable strict mode to silence one error invariably rediscover this the hard way when a truncated email or a zeroed-out price reaches a customer.

Check the mode with SELECT @@SESSION.sql_mode and note that session and global values can differ — connectors, ORMs, and init scripts can and do override it per connection.

📊 Production Insight
The classic production surprise: the app's DSN sets session sql_mode without anyone remembering. GLOBAL shows strict, the failing connection shows lax (or the reverse), and two engineers stare at identical my.cnf files wondering why behavior differs.
🎯 Key Takeaway
STRICT_TRANS_TABLES turns silent data corruption into loud errors — it's the reason 1364 exists, and disabling it trades one error for hidden corruption.

NOT NULL Without DEFAULT: Find Every Risky Column

A column throws 1364 only when two conditions hold at once: it's NOT NULL and it has no DEFAULT. Either condition alone is harmless — a nullable column accepts the omission as NULL, and a NOT NULL column with DEFAULT fills in the fallback. The dangerous combination usually arrives via migration: someone adds plan VARCHAR(20) NOT NULL to a live table without a DEFAULT, or scaffolding generates a model whose migration omits defaults entirely.

MySQL's implicit-default rules make this sneakier than it sounds. On a lenient server, omitting the column appears to work — the row lands with an empty string or zero — so the missing DEFAULT goes unnoticed for months. The day anyone enables strict mode, upgrades MySQL, or points the app at a properly configured replica, every one of those INSERTs starts failing at once. The schema was always broken; strictness just exposed it.

TIMESTAMP columns deserve special attention because they historically behaved differently: the first TIMESTAMP in a table auto-defaulted to CURRENT_TIMESTAMP, which masked omissions. MySQL 5.6.5+ removed most of that magic behind explicit_defaults_for_timestamp, so TIMESTAMP columns now throw 1364 like everything else. If your legacy schema leans on implicit timestamp defaults, an upgrade will surface them all as 1364s.

Audit the whole table with one INFORMATION_SCHEMA query that lists every NOT NULL column lacking a default. Run it after every migration — it takes a second and catches the exact columns that will fail next.

SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- Find every column in a table that can throw 1364.
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
  AND TABLE_NAME = 'signups'
  AND IS_NULLABLE = 'NO'
  AND COLUMN_DEFAULT IS NULL;

-- Same audit across a whole schema, grouped by table.
SELECT TABLE_NAME, GROUP_CONCAT(COLUMN_NAME) AS risky_columns
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
  AND IS_NULLABLE = 'NO'
  AND COLUMN_DEFAULT IS NULL
  AND EXTRA NOT LIKE '%auto_increment%'
GROUP BY TABLE_NAME;
📊 Production Insight
TIMESTAMP columns are the repeat offenders in legacy schemas. Code that relied on pre-5.6 implicit timestamp defaults breaks on upgrade with a burst of 1364s that look unrelated until you check explicit_defaults_for_timestamp.
🎯 Key Takeaway
NOT NULL without DEFAULT is the loaded gun; strict mode just pulls the trigger — audit INFORMATION_SCHEMA after every migration.

Fix the INSERT: Name Every Required Column

The most common 1364 has nothing wrong with the schema — the INSERT is just incomplete. INSERT INTO signups (email) VALUES (...) skips plan, and strict MySQL refuses to guess. The fix at the query level is to name every required column and supply a value: INSERT INTO signups (email, plan) VALUES ('a@example.com', 'free'). Explicit column lists also protect you against column-order changes from later migrations, which bare VALUES lists silently absorb until types shift and stranger errors appear.

ORMs add a layer of indirection that makes this harder to see. You set user.plan = 'free' in code, but a mass-assignment guard, a serializer field list, or a renamed form parameter strips it before the SQL is built. The generated INSERT omits the column, MySQL throws 1364, and the application log shows a model that clearly had the value. The only reliable evidence is the SQL itself — enable query logging in staging and read the actual INSERT.

Bulk paths deserve the same scrutiny. LOAD DATA, INSERT ... SELECT, and multi-row VALUES lists all throw 1364 when a required target column has no source. With INSERT ... SELECT, the column mapping is positional, so a SELECT that returns three columns into a four-column target fails even when names look right. Always write the target column list explicitly and count both sides.

Make the explicit INSERT your default habit: list columns, bind values, and let code review catch omissions before strict mode has to.

SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
-- Minimal reproduction: NOT NULL with no DEFAULT, INSERT omits it.
CREATE TABLE signups (
  id INT AUTO_INCREMENT PRIMARY KEY,
  email VARCHAR(255) NOT NULL,
  plan VARCHAR(20) NOT NULL
);

-- This fails under strict mode with ERROR 1364.
-- INSERT INTO signups (email) VALUES ('a@example.com');

-- Fix at the query level: name every required column.
INSERT INTO signups (email, plan) VALUES ('a@example.com', 'free');
SELECT * FROM signups;
📊 Production Insight
Bulk imports are where query-level 1364s hide: a CSV loader that worked for a year breaks the day a column is added, because the field mapping silently stops covering the new NOT NULL column.
🎯 Key Takeaway
Name every NOT NULL column in the INSERT with an explicit list — and when an ORM is involved, verify with the generated SQL, not the model state.

Add a DEFAULT vs Relax sql_mode: Choose Correctly

When the INSERT is correct and complete yet 1364 persists, the schema needs a DEFAULT. ALTER TABLE signups ALTER COLUMN plan SET DEFAULT 'free' gives MySQL an explicit fallback, so any future INSERT that omits plan succeeds deterministically instead of depending on server mood. For new columns, prefer defining the default inline: ADD COLUMN plan VARCHAR(20) NOT NULL DEFAULT 'free'. Defaults are documentation — they state what the value means when nobody says otherwise.

The alternative — removing STRICT_TRANS_TABLES from sql_mode — is the most damaging popular advice for this error. It doesn't fix anything; it reverts MySQL to guessing. Truncated strings land silently, invalid dates become zero-dates, and the next strict replica or upgraded server resurrects every hidden bug at once. Worse, sql_mode can be set globally, per session, and in client flags, so a 'quick' relaxation in one place creates behavior that differs by connection and vanishes on restart.

There's exactly one legitimate use for touching sql_mode around 1364: diagnosis. SET SESSION sql_mode to a lax value on a scratch connection to confirm strictness is the trigger, then revert and fix properly. Never SET GLOBAL on production, never bake the relaxation into my.cnf, and never let a Stack Overflow snippet talk you into sql_mode=''.

Choose defaults deliberately: a sentinel like 'free' or 0 that downstream code already handles. A default nobody recognizes is just corruption with a stamp on it.

SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
-- Lasting schema fix: give the column an explicit DEFAULT.
ALTER TABLE signups ALTER COLUMN plan SET DEFAULT 'free';

-- Equivalent for new columns: declare the default inline.
-- ALTER TABLE signups ADD COLUMN status VARCHAR(20) NOT NULL DEFAULT 'active';

-- Verify: omitting the column now uses the default, no error.
INSERT INTO signups (email) VALUES ('b@example.com');
SELECT email, plan FROM signups;

-- Diagnose-only: confirm strictness is the trigger on a SCRATCH session.
-- SET SESSION sql_mode = '';
-- Remember to revert: SET SESSION sql_mode = 'STRICT_TRANS_TABLES';
⚠ Don't Relax sql_mode to Fix One Error
Stripping STRICT_TRANS_TABLES silences 1364 along with truncation errors, zero-date rejection, and out-of-range checks — your whole strict safety net goes dark for one convenience. Fix the query or add a DEFAULT instead.
📊 Production Insight
DEFAULT choices become permanent API: reports, exports, and billing logic will eventually read the fallback value. Pick one the business understands ('free', 0, 'unknown'), not whatever silences the error fastest.
🎯 Key Takeaway
Add an explicit DEFAULT for resilience; reserve sql_mode changes for scratch diagnosis — never as the production fix.

Reconcile Environments: Dev, Staging, and Prod

Error 1364 loves environment gaps because sql_mode is configuration, not code. Your laptop's Homebrew MySQL, the CI container's official image, staging's managed database, and production's tuned instance can each carry a different sql_mode — and the same INSERT passes on three and fails on one. Docker images default to strict, while some managed providers and legacy AMIs historically shipped laxer modes, so containerizing an old app is a classic 1364 trigger.

Upgrades are the other great revealer. Moving from 5.6 to 5.7+ flips strict on by default; moving to 8.0 tightens timestamp handling on top. The queries didn't change — the contract did. Any upgrade runbook should include a strict-mode audit: dump the schema, list NOT NULL-without-DEFAULT columns, and run the app's write paths against a strict staging instance before cutover.

Reconcile environments with three habits. First, pin sql_mode explicitly in my.cnf under [mysqld] on every server and deploy that file with the same automation — never rely on compiled-in defaults. Second, compare modes as part of deploy checks: SELECT @@GLOBAL.sql_mode on each tier and fail the deploy on drift. Third, make CI strict: run tests against the official MySQL image with default flags so lax local settings can't hide 1364s that production will throw.

Parity beats debugging. Every hour spent aligning environments saves three spent chasing errors that only exist in one place.

BASH
1
2
3
4
5
6
7
8
9
10
11
12
# Compare schema + mode across two environments before blaming code.
mysqldump --no-data shop > /tmp/schema-staging.sql
ssh prod-db 'mysqldump --no-data shop' > /tmp/schema-prod.sql
diff /tmp/schema-staging.sql /tmp/schema-prod.sql

mysql -h staging-db -e "SELECT @@GLOBAL.sql_mode;"
mysql -h prod-db -e "SELECT @@GLOBAL.sql_mode;"

# Pin the mode in my.cnf so defaults can't drift.
# /etc/mysql/my.cnf  (or /etc/my.cnf.d/server.cnf)
# [mysqld]
# sql_mode = STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
📊 Production Insight
Managed databases add a twist: some providers don't let you edit my.cnf directly and expose sql_mode through parameter groups instead. A lift-and-shift that forgets the parameter group inherits the provider's default mode — audit it the same week you migrate.
🎯 Key Takeaway
Pin sql_mode in my.cnf everywhere, assert parity at deploy time, and run CI against strict defaults so no environment can hide a 1364.
● Production incidentPOST-MORTEMseverity: high

A Framework Upgrade Silently Dropped a Field and Broke Signups for 3 Hours

Symptom
New user signups returned 500 errors for 3 hours starting right after a routine framework minor upgrade. The logs showed ERROR 1364 (HY000): Field 'plan' doesn't have a default value on every signup INSERT. Existing users were unaffected — only the create-account path failed, and the failure rate was 100%, not intermittent.
Assumption
The team blamed the schema. A migration the previous week had added the plan column, so everyone assumed the migration was broken. Two engineers spent an hour diffing migration files and re-running them on staging, where everything worked. The schema looked identical in both places, which deepened the confusion — the table definitions matched, yet only production failed.
Root cause
A framework minor upgrade changed mass-assignment behavior: fields not explicitly whitelisted were now stripped before query building instead of passed through. The plan attribute was set on the model in code, but the generated INSERT omitted the plan column entirely. Local dev didn't catch it because dev ran without STRICT_TRANS_TABLES, so MySQL silently coerced the missing value to an empty string. Production ran strict, so the same INSERT threw 1364.
Fix
The lasting fix had two parts. First, the hotfix: ALTER TABLE signups ALTER COLUMN plan SET DEFAULT 'free' so new INSERTs survived even when the ORM dropped the field. Second, the real fix: the plan field was added to the model's fillable whitelist and a staging test was added that asserts the generated INSERT names every NOT NULL column. The team also pinned sql_mode in my.cnf on all environments and added a deploy-time check comparing INFORMATION_SCHEMA output against the ORM's column list.
Key lesson
  • Error 1364 names the victim column, not the culprit — the missing value often comes from an ORM guard or serializer, not the schema.
  • Identical schemas can still behave differently when sql_mode or client flags diverge — always compare session variables, not just CREATE TABLE output.
  • A DEFAULT is a safety net, not a substitute for sending the value — add the default for resilience, then fix the code path that dropped the field.
Production debug guideFive checks that separate query bugs from schema bugs from environment drift — run them in order.5 entries
Symptom · 01
ERROR 1364 names a column your INSERT never mentioned
→
Fix
Run SHOW CREATE TABLE orders and read the column list. Every line ending in NOT NULL with no DEFAULT clause is a column your INSERT must name. Then run SELECT @@SESSION.sql_mode and confirm STRICT_TRANS_TABLES or STRICT_ALL_TABLES appears — that flag is what turns the omission into a fatal error instead of a silent coercion.
Symptom · 02
You need a full list of columns that could throw 1364
→
Fix
Run SELECT COLUMN_NAME, IS_NULLABLE, COLUMN_DEFAULT, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'orders' AND IS_NULLABLE = 'NO' AND COLUMN_DEFAULT IS NULL. Every row returned is a column that will throw 1364 whenever an INSERT skips it. Compare that list against the column list in your application's INSERT statement to spot the omission.
Symptom · 03
Same query fails in one environment but passes in another
→
Fix
Run SELECT @@GLOBAL.sql_mode then SELECT @@SESSION.sql_mode and diff them. If GLOBAL is strict but SESSION isn't (or vice versa), something — a client flag, an ORM initializer, or a SET statement — is overriding the mode per connection. Search the codebase for sql_mode and check the DSN string for sessionVariables parameters that rewrite the mode on connect.
Symptom · 04
Your code sets the value but MySQL says it's missing
→
Fix
Enable the general query log briefly with SET GLOBAL general_log = 1, reproduce the failing request, then grep the log for the INSERT: tail -n 200 /var/lib/mysql/localhost.log | grep -i insert. You'll see the exact column list MySQL received — often shorter than what the code set, because an ORM guard or serializer dropped a field before the query was built.
Symptom · 05
Staging passes but production throws 1364
→
Fix
Run mysqldump --no-data shop > /tmp/schema.sql on both servers and diff the CREATE TABLE blocks for the failing table. Then compare SELECT @@GLOBAL.sql_mode on each. Schema drift (a migration applied in one place) and mode drift (different my.cnf files) are the two classic reasons staging passes while production throws 1364.
MySQL 1364 Root Causes — Confirm and Fix Each One
Root CauseHow to ConfirmFixPrevention
INSERT omits a NOT NULL column with no DEFAULTRun SHOW CREATE TABLE and compare its NOT NULL columns against your INSERT column listName every NOT NULL column in the INSERT or give the column a DEFAULTAdd integration tests that insert with the app's real queries, not hand-built ones
STRICT_TRANS_TABLES enabled (MySQL 5.7+ default)SELECT @@SESSION.sql_mode shows STRICT_TRANS_TABLES or STRICT_ALL_TABLESFix the query or schema — don't strip the strict flagPin sql_mode in my.cnf and assert it in CI so envs can't drift
Column added later without a DEFAULTINFORMATION_SCHEMA shows IS_NULLABLE=NO and COLUMN_DEFAULT=NULL for the new columnBackfill existing rows, then ALTER TABLE to add a DEFAULTMake every migration that adds NOT NULL also set a DEFAULT or backfill
ORM silently drops a field (mass-assignment guard)Enable query logging and compare bound parameters against the INSERT listWhitelist the field in fillable/serializer config or set a DB defaultLog generated SQL in staging and alert when an INSERT omits a column
⚙ Quick Reference
5 commands from this guide
FileCommand / CodePurpose
SHOW CREATE TABLE signups;Read the Error Line Before You Touch Anything
SELECT COLUMN_NAME, DATA_TYPE, IS_NULLABLE, COLUMN_DEFAULTNOT NULL Without DEFAULT
CREATE TABLE signups (Fix the INSERT
ALTER TABLE signups ALTER COLUMN plan SET DEFAULT 'free';Add a DEFAULT vs Relax sql_mode
mysqldump --no-data shop > /tmp/schema-staging.sqlReconcile Environments

Key takeaways

1
Error 1364 means strict mode refused to invent a value for a missing NOT NULL column
name the column or default it.
2
STRICT_TRANS_TABLES is the tripwire, not the villain
keep it on and fix the query or schema instead.
3
Audit with INFORMATION_SCHEMA for IS_NULLABLE=NO plus COLUMN_DEFAULT=NULL to find every future 1364.
4
Adding a DEFAULT beats relaxing sql_mode
one protects data, the other hides whole error classes.
5
ORMs can drop fields before INSERT
log generated SQL in staging to catch silent omissions.
6
Pin sql_mode in my.cnf on every environment so dev, staging, and prod can't silently diverge.

Common mistakes to avoid

5 patterns
×

Omitting columns from INSERT and relying on implicit defaults

Symptom
ERROR 1364 names a column you never mentioned in your query, and the same code worked on an older MySQL with lax sql_mode.
Fix
List every NOT NULL column explicitly in the INSERT, or add a DEFAULT to the column. If the column is genuinely optional, change it to NULL instead of fighting the constraint.
×

Disabling STRICT_TRANS_TABLES to silence the error

Symptom
The error vanishes but zero-dates, truncated strings, and empty values start polluting tables, and a later strict replica fails replication.
Fix
Keep strict mode on everywhere. Fix the query or add a DEFAULT. If you must compare behaviors, use SET SESSION sql_mode on a scratch connection — never SET GLOBAL on production.
×

Adding a NOT NULL column to a populated table without a DEFAULT

Symptom
The ALTER succeeds on an empty dev database but the deploy migration fails on production, or new INSERTs start throwing 1364 right after release.
Fix
Always write migrations as: add column NULL, backfill, then ALTER to NOT NULL with a DEFAULT. Test the migration against a production-sized snapshot, not an empty schema.
×

Forgetting that the ORM strips unlisted fields before INSERT

Symptom
The model sets the attribute in code, but the generated INSERT omits it and MySQL throws 1364 for a value you thought you supplied.
Fix
After changing fillable lists, serializers, or form fields, run the app's real create-flow in staging with SQL logging on and confirm the INSERT names every required column.
×

Assuming dev, staging, and prod share the same sql_mode

Symptom
Code passes locally and in CI, then throws 1364 on the first production deploy because prod runs STRICT_TRANS_TABLES and dev doesn't.
Fix
Store sql_mode in my.cnf under [mysqld], deploy that file with the same automation everywhere, and add a startup check that fails fast when the mode differs from the pinned value.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What does MySQL error 1364 mean, and what's the first fix you'd try?
Q02JUNIOR
What does STRICT_TRANS_TABLES do, and why does it surface 1364?
Q03SENIOR
How would you find every column that could throw 1364 for a table?
Q04SENIOR
Why is removing STRICT_TRANS_TABLES a bad fix for 1364?
Q05SENIOR
New code throws 1364 in production but passes in staging. Walk through y...
Q01 of 05JUNIOR

What does MySQL error 1364 mean, and what's the first fix you'd try?

ANSWER
It means an INSERT didn't supply a value for a NOT NULL column that has no DEFAULT, and strict mode refused to guess one. The fix is to include the column in the INSERT with an explicit value, add a DEFAULT to the column definition, or allow NULL if the business logic permits it.
FAQ · 6 QUESTIONS

Frequently Asked Questions

01
Does 1364 apply to AUTO_INCREMENT primary keys I've skipped?
02
Why can't I just add a DEFAULT to a TEXT column?
03
Is 1364 the same as error 1265 data-truncated?
04
Did MySQL 5.7 make this error more common?
05
Does SET GLOBAL sql_mode change every connection permanently?
06
How do I audit a whole schema for future 1364s?
N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Written from production experience, not tutorials.

Follow
✓ Verified
production tested
September 24, 2026
last updated
1,942
articles · all by Naren
🔥

That's MySQL. Mark it forged?

6 min read · try the examples if you haven't

←
Previous
Redis MISCONF RDB Snapshot Fix
6 / 7 · MySQL
Next
PyMySQL 2003 Cant Connect Fix
→