Home Database ORA-01400 Cannot Insert NULL — Default or Column Fix
Beginner 5 min · September 23, 2026

ORA-01400 Cannot Insert NULL — Default or Column Fix

Fix Oracle ORA-01400 by naming the missing column, backfilling a default, or relaxing NOT NULL.

N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Drawn from code that ran under real load.

Follow
Production
production tested
September 23, 2026
last updated
1,905
articles · all by Naren
Before you start⏱ 10 min
  • An Oracle database (11g+) with dictionary access
  • The failing INSERT text and the schema it targets
  • Permission to read all_tab_columns and all_triggers
 ● Production Incident 🔎 Debug Guide
Quick Answer
  • ORA-01400 means your INSERT (or UPDATE) tried to put NULL into a NOT NULL column — the message names the exact schema, table, and column, so start there
  • The usual trigger is an INSERT without a column list after someone added a column, or an INSERT whose list quietly omits the new NOT NULL column
  • Check for autopopulation: sequences and BEFORE INSERT triggers normally fill PKs and audit columns — a disabled trigger or a missing NEXTVAL call exposes the raw NULL
  • Fix by supplying the value, adding a DEFAULT, or backfilling then constraining — and use NVL/COALESCE at write time so optional inputs degrade to sane defaults
✦ Definition~90s read
What is ORA-01400 Cannot Insert NULL Fix?

ORA-01400 is raised when an INSERT or UPDATE would store NULL in a column constrained NOT NULL. The message identifies all three parts — schema, table, column — so diagnosis starts at the dictionary, not the code. NOT NULL is enforced per row at write time for both direct DML and path loads (SQL*Loader direct path included), and it applies equally to explicit NULLs and to columns simply omitted from an INSERT without a column list.

Picture a paper form where the social-security field is marked mandatory in red ink.

Four mechanisms normally keep NULLs out, and each is a failure mode when broken. Explicit column lists: INSERT INTO t (a, b) VALUES (1, 2) leaves every unlisted column to its DEFAULT or NULL — add a NOT NULL column later and every old list breaks. Column DEFAULTs: DEFAULT 'new' fills omitted columns automatically, but only if the default was declared.

BEFORE INSERT triggers: legacy auto-population for PKs (sequence.NEXTVAL), audit stamps, and derived values — disable or drop the trigger and raw NULLs hit the constraint. Identity columns and 12c defaults: modern autopopulation that still fails when an explicit NULL overrides the generated value.

The fix direction depends on intent. If the column is genuinely mandatory, supply the value everywhere (fix the INSERT lists) or declare a DEFAULT so omission is safe. If writes legitimately lack the value, the column isn't mandatory — relax to NULL. If rows predate the rule, backfill first, then constrain. Matching the remedy to the intent is the whole art; the error itself can't tell you which.

Plain-English First

Picture a paper form where the social-security field is marked mandatory in red ink. ORA-01400 is the clerk sliding the form back: you left a box empty. Maybe a new required box was added after the forms were printed (a column added without a default), maybe the stamp that auto-fills the box is broken (a disabled trigger), or maybe you simply skipped it. The remedies match: fill the box, install a stamp that fills it for you (DEFAULT), or admit the box was never mandatory (drop NOT NULL).

ORA-01400: cannot insert NULL into ("SHOP"."ORDERS"."STATUS"). It lands right after a schema change, an ETL tweak, or a framework upgrade — inserts that ran for years suddenly rejected, with the message naming the exact column. The application didn't change; the contract did. Somebody added a NOT NULL column without a default, disabled a populating trigger, or deployed code whose INSERT list predates the new column.

Oracle enforces NOT NULL at write time with zero forgiveness: no implicit defaults, no silent coercion. That strictness is a feature — it keeps junk out — but it turns every uncoordinated schema change into a write outage for exactly the paths nobody updated.

This guide follows the message inward: reading the three-part name, auditing the column's nullability and default, finding the stale INSERT, checking sequences and triggers, defaulting with NVL/COALESCE, and adding future NOT NULL columns without breaking live writes. The same discipline covers every database with mandatory-column errors.

Read the Three-Part Name in the Message

cannot insert NULL into ("SHOP"."ORDERS"."STATUS") hands you owner, table, and column in one breath — no log archaeology needed. Go straight to all_tab_columns for that coordinate and read two fields: NULLABLE (Y/N) and DATA_DEFAULT. N with no default means omission is fatal and explicit NULL is fatal; the write must supply the value or the schema must change. N with a default means someone passed explicit NULL — the default only fills omitted columns, never overrides.

While there, read the neighbors: how many other NOT NULL-without-default columns share the table, and which of them your INSERT lists cover. A table that grew three mandatory columns across three migrations usually breaks three different write paths — fixing only the named one buys days, not safety. The dictionary view of the whole table turns a single-column incident into a complete audit in one query.

Record the coordinate plus the NULLABLE/DEFAULT pair in the ticket. 'SHOP.ORDERS.STATUS is N with no default' tells the next engineer everything; 'insert failing' tells them nothing. Precision at this step compresses every later one. Paste the coordinate into the ticket title so the next engineer starts at the dictionary, not at zero.

audit_column_1400.sqlSQL
1
2
3
4
5
6
7
8
9
10
-- The named column: nullability + default in one row
SELECT nullable, data_default, data_type
FROM all_tab_columns
WHERE owner = 'SHOP' AND table_name = 'ORDERS' AND column_name = 'STATUS';

-- Whole-table audit: every mandatory column without a default
SELECT column_name, data_type
FROM all_tab_columns
WHERE owner = 'SHOP' AND table_name = 'ORDERS'
  AND nullable = 'N' AND data_default IS NULL;
📊 Production Insight
One dictionary query showed STATUS as N with no default — the migration's missing DEFAULT named in ten seconds, after 15 minutes wasted on payment dashboards.
🎯 Key Takeaway
The message names owner, table, column — read NULLABLE plus DATA_DEFAULT there before touching code.

The Missing Column in the INSERT List

INSERT INTO orders VALUES (...) without a column list binds by position and breaks on every schema change; INSERT with a list breaks only when a new mandatory column goes unlisted. Both fail identically with 01400, but the list form tells you exactly what's missing by diffing. Always write lists — positional inserts are a standing invitation to the next outage.

The subtle variant is the explicitly-NULL bind: INSERT INTO orders (..., status) VALUES (..., NULL) fails even when status has a DEFAULT, because explicit NULL overrides defaults. ORMs love this shape — they bind every mapped attribute, NULLs included. The fix is omitting null-valued columns from the statement (dynamic SQL), wrapping with NVL, or declaring DEFAULT ON NULL so the column treats explicit NULLs as omitted.

Diff mechanically, not by eye: extract the statement's column list and compare against the mandatory-no-default set from the dictionary. Eyes skip the 14th column in a 20-column list; a set difference doesn't. Attach that diff to the deploy checklist for every migration touching the table. Better yet, generate the diff in CI from the migration files themselves — the checklist then verifies what the pipeline already proved.

insert_list_fix.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
-- Positional (breaks on every schema change): avoid
-- INSERT INTO orders VALUES (1, 881, 5000);

-- Explicit list naming the new column (survives schema growth)
INSERT INTO orders (order_id, customer_id, total, status)
VALUES (1, 881, 5000, 'new');

-- Omit-when-null pattern: DEFAULT fills what you skip
INSERT INTO orders (order_id, customer_id, total)
VALUES (2, 882, 7500);
-- (works only if status has a DEFAULT)
💡Name Every Column, Every Time
INSERTs without column lists break on any schema change; lists break only on unlisted mandatory columns — and the diff names the fix. Ban positional INSERTs in review.
📊 Production Insight
The order service's list predated the new column by one deploy. A CI diff of lists versus mandatory columns would have failed the migration's build.
🎯 Key Takeaway
Write explicit INSERT lists, diff them against mandatory-no-default columns, and never bind explicit NULLs over defaults.

Sequences, Identity, and Trigger Defaults

Primary keys and audit columns usually arrive via autopopulation — and every mechanism has an off switch that produces 01400. Legacy BEFORE INSERT triggers calling seq.NEXTVAL stop firing when disabled, dropped, or invalidated by a dependency change; direct-path loads and some bulk tools bypass row triggers entirely, exposing the raw NULL beneath. Sequence-fed inserts fail differently: forgetting NEXTVAL in the VALUES clause inserts NULL into the PK with the same code.

Diagnose the chain in order: all_triggers for STATUS (DISABLED is the smoking gun), then the trigger body for the assignment (SELECT trigger_body FROM all_triggers), then whether the failing path fires triggers at all. For identity columns (GENERATED ALWAYS AS IDENTITY), check for explicit NULL/0 overrides — ALWAYS rejects caller-supplied values, while BY DEFAULT ON NULL accepts NULLs gracefully.

Repair the mechanism, not the rows. Re-enable and recompile the trigger (ALTER TRIGGER ... ENABLE, check USER_ERRORS for invalidation causes), restore NEXTVAL to the insert, or migrate legacy trigger-population to identity columns that can't be disabled. Hand-filling one incident's NULLs without fixing the populator guarantees the sequel.

autopop_1400.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
-- Trigger chain: present? enabled? valid?
SELECT trigger_name, status FROM all_triggers
WHERE table_owner = 'SHOP' AND table_name = 'ORDERS';
SELECT trigger_body FROM all_triggers
WHERE trigger_name = 'ORDERS_BI_TRG';

-- Repair: re-enable (then check USER_ERRORS if invalid)
ALTER TRIGGER shop.orders_bi_trg ENABLE;

-- Sequence-fed PK done right
INSERT INTO orders (order_id, customer_id, total, status)
VALUES (shop.order_seq.NEXTVAL, 881, 5000, 'new');
📊 Production Insight
A bulk tool bypassed the row trigger that filled audit columns — thousands of 01400s with the trigger 'fine'. The path, not the trigger, was the bug.
🎯 Key Takeaway
Check trigger STATUS, trigger bodies, and NEXTVAL usage — then repair the populator instead of hand-filling rows.

NVL/COALESCE: Defaulting at Write Time

When inputs are legitimately absent — an optional status from an older client, a nullable API field — default at write time instead of failing. NVL(:status, 'new') substitutes the fallback per row; COALESCE takes the first non-NULL across several candidates (request value, customer default, global default). Both keep the INSERT list stable while inputs vary, which is exactly the shape that survives schema growth.

Prefer schema DEFAULTs for universal fallbacks and NVL/COALESCE for contextual ones. A column default ('new' for every omitted status) belongs in DDL where every writer inherits it; a contextual pick (VIP customers default to 'priority') belongs in the statement where the logic stays visible to reviewers. Mixing them up — contextual logic in DDL via triggers, universal defaults repeated in every INSERT — scatters the contract across layers.

On 12c+, DEFAULT ON NULL closes the explicit-NULL hole declaratively: omitted and explicit-NULL both resolve to the default, so ORM-bound NULLs stop throwing for good. Adopt it for every defaulted column that ORMs touch in any write path — it's the one-line end to an entire class of binding bugs that otherwise recur quarterly. Document which columns use it beside the schema contract so every writer inherits the behavior.

nvl_coalesce_1400.sqlSQL
1
2
3
4
5
6
7
8
9
10
-- Contextual fallback at write time
INSERT INTO orders (order_id, customer_id, total, status)
VALUES (3, 883, 9000, NVL(:status, 'new'));

-- First non-NULL across candidates
INSERT INTO orders (order_id, customer_id, total, status)
VALUES (4, 884, 9100, COALESCE(:status, :cust_default, 'new'));

-- Declarative end to explicit-NULL bindings (12c+)
ALTER TABLE shop.orders MODIFY status DEFAULT ON NULL 'new';
📊 Production Insight
An older mobile client sent no status field at all — NVL at write time plus a schema DEFAULT absorbed three app generations without another 01400.
🎯 Key Takeaway
NVL/COALESCE for contextual fallbacks, DDL DEFAULTs for universal ones, DEFAULT ON NULL for ORM-bound columns.

Backfill Then Constrain: Adding NOT NULL Safely

Adding NOT NULL to a populated table is a three-step dance, and skipping a step is how outages happen. First UPDATE the existing NULLs to the intended value (or a marked sentinel you reconcile later) — on big tables, batch the update to avoid a megatransaction that stalls replication and holds TM locks. Then declare the DEFAULT so future omissions land safely. Only then ADD the constraint — with VALIDATE on small tables, and ENABLE NOVALIDATE plus a later VALIDATE on huge ones to avoid a full-table lock during peak.

The migration that caused the incident did step three first (well, simultaneously): NOT NULL with no default and no service-list check. The safe template inverts the risk — backfill, default, constrain — with each step independently deployable and rollback-safe. Defaults are the shock absorbers: they let old write paths keep working while new code adopts the column deliberately.

Verify after constraining: re-run the mandatory-no-default audit (the new column should now show a default or full list coverage), insert one row omitting the column to prove the default fires, and watch the alert log for 01400 in the hour after deploy. The migration isn't done when it runs clean — it's done when the first real writes prove the contract.

safe_notnull.sqlSQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
-- 1) Backfill existing NULLs (batch on big tables)
UPDATE shop.orders SET status = 'new'
WHERE status IS NULL AND ROWNUM <= 100000;
-- repeat until 0 rows updated

-- 2) Declare the default (absorbs future omissions)
ALTER TABLE shop.orders MODIFY status DEFAULT 'new';

-- 3) Constrain last (NOVALIDATE + later VALIDATE on huge tables)
ALTER TABLE shop.orders MODIFY status NOT NULL;

-- Prove the contract: omitted column must default, not fail
INSERT INTO shop.orders (order_id, customer_id, total)
VALUES (5, 885, 9200);
⚠ Constrain Last, Never First
Adding NOT NULL before backfilling and defaulting fails existing NULLs and breaks live writes simultaneously. Backfill, then DEFAULT, then constrain — each step provable before the next.
📊 Production Insight
The incident migration ran NOT NULL with no default and no list check — clean run, dead writes. The backfill-default-constrain template has shipped 40 columns since without a page.
🎯 Key Takeaway
Backfill NULLs, declare DEFAULT, then constrain — and prove the contract with a real omitted-column insert.

Prevention: Schema Contracts in CI

Make uncoordinated columns structurally impossible. The migration rule is one sentence: every new NOT NULL column declares a DEFAULT unless the owning service's updated INSERT list is attached to the same pull request. Reviewers enforce the sentence; the pipeline enforces the proof — a job that diffs each service's INSERT lists against the mandatory-no-default set and fails the build on any gap.

Monitor the error as a deploy signal, not just an incident. Alert on the first ORA-01400 in the alert log after any DDL deploy: one occurrence pages, because the first is never the last when a write path is broken. Trend 01400 counts per table across releases — a step-change names the migration that introduced the mismatch even when nobody connects the two.

Version the write contract alongside the schema itself. The service's INSERT lists are as much an interface as its REST endpoints; changing mandatory columns without updating consumers breaks the interface. Treat DDL review with the same consumer-impact rigor as API review, and the 'surprise mandatory column' stops shipping. Publish the contract (mandatory columns per table) where service owners can read it without asking the DBA team.

contract_gate_1400.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/bin/bash
# Deploy gate: no 01400 may follow a DDL deploy; mandatory columns covered
set -euo pipefail
CONNECT="svc/pass@//db-prod:1521/shop"
# 1) Any 01400 since the deploy marker?
CNT=$(sqlplus -S "$CONNECT" << 'EOF'
SET HEADING OFF FEEDBACK OFF
SELECT COUNT(*) FROM v$diag_alert_ext
WHERE message_text LIKE '%ORA-01400%' AND originating_timestamp > SYSTIMESTAMP - INTERVAL '1' HOUR;
EOF
)
echo "ORA-01400 in last hour: $CNT" | tr -d ' '
# 2) Mandatory-no-default columns must all have service coverage (reviewed list)
sqlplus -S "$CONNECT" << 'EOF'
SELECT column_name FROM all_tab_columns
WHERE owner='SHOP' AND table_name='ORDERS'
  AND nullable='N' AND data_default IS NULL;
EOF
echo GATE-CHECK-DONE
📊 Production Insight
A CI diff of INSERT lists versus mandatory columns now fails the build that would have caused the 45-minute outage — the exact migration, caught pre-merge.
🎯 Key Takeaway
Require DEFAULT-or-list-coverage per migration, alert on the first post-DDL 01400, and review DDL like API changes.
● Production incidentPOST-MORTEMseverity: high

A NOT NULL Column Without Default Blocked Orders for 45 Minutes

Symptom
At 2:15 PM a schema migration added status VARCHAR2(10) NOT NULL to orders with no DEFAULT. By 2:16 PM every checkout failed with ORA-01400 on SHOP.ORDERS.STATUS — 310 failed orders in 20 minutes, 100% of write traffic. Reads stayed green, so monitoring took 8 minutes to page on the write-error rate. The mobile app showed a generic failure screen; 40 customers were charged by the payment provider before the database write failed, creating 40 orphan payments needing reconciliation.
Assumption
The team assumed the payment provider was rejecting transactions and failed over the payment integration — twice — while the database kept refusing writes. Fifteen minutes went to payment dashboards that showed successful authorizations, which only deepened the confusion until someone read the app log's ORA-01400 line.
Root cause
The migration (written for a backfilled warehouse table) declared status NOT NULL without DEFAULT, and the order service's explicit INSERT list didn't include status. Two gaps compounded: no DEFAULT to absorb omitted columns, and no contract test asserting the service's INSERT list matches the table's mandatory columns. The migration ran clean (existing rows were backfilled first), so the deploy looked safe while every new write died.
Fix
At 3:00 PM they ran ALTER TABLE orders MODIFY status DEFAULT 'new' — new writes recovered instantly as omitted columns defaulted. The 40 orphan payments were reconciled against provider records the same evening. Follow-ups: the service INSERT now names status explicitly, a CI check diffs INSERT lists against NOT NULL columns without defaults, and the migration rule requires DEFAULT on every new NOT NULL column unless the owning service confirms its list first.
Key lesson
  • Every new NOT NULL column ships with a DEFAULT unless the owning service proves its INSERT list covers it — defaults absorb omission, constraints reject it.
  • Read the three-part name in the message first: schema, table, column in hand, the dictionary answers nullability and default in one query.
  • Contract-test write paths against the schema: diffing INSERT lists against mandatory columns in CI turns a 45-minute outage into a failed build.
Production debug guideSix checks from the named column to the stale write path.6 entries
Symptom · 01
INSERT fails with ORA-01400 naming ("SCHEMA"."TABLE"."COLUMN")
Fix
Audit the column: SELECT nullable, data_default FROM all_tab_columns WHERE owner = 'SHOP' AND table_name = 'ORDERS' AND column_name = 'STATUS'; NULLABLE='N' with no DATA_DEFAULT means omission is fatal — exactly your error. If a default exists, the write is passing explicit NULL (overriding the default), which points at the application's bind values, not the list.
Symptom · 02
Column is NOT NULL without default — who omits it?
Fix
Pull the failing INSERT text from the app log or v$sql and compare its column list against the mandatory set: SELECT column_name FROM all_tab_columns WHERE owner='SHOP' AND table_name='ORDERS' AND nullable='N' AND data_default IS NULL; Every name in that result must appear in the INSERT list (or come from a trigger). The missing name is the diff that fixes the outage.
Symptom · 03
The column should be auto-populated (PK, audit stamp)
Fix
Check the autopopulation chain: SELECT trigger_name, status FROM all_triggers WHERE table_owner='SHOP' AND table_name='ORDERS'; — a DISABLED trigger explains vanished defaults. For sequence-fed PKs, confirm the INSERT calls seq.NEXTVAL (or the column is IDENTITY/DEFAULT ON NULL). Re-enable or repair the mechanism rather than hand-filling values per row.
Symptom · 04
You need writes flowing before the code deploys
Fix
Add the safety net at the schema level: ALTER TABLE shop.orders MODIFY status DEFAULT 'new'; New omissions now default instead of failing — service recovers without a code deploy. Backfill existing NULLs first if any slipped in during the window: UPDATE shop.orders SET status='new' WHERE status IS NULL; (there should be none — 01400 blocks them — but verify).
Symptom · 05
Bind values pass explicit NULLs over a defaulted column
Fix
Prove it with the insert text: INSERT INTO t (status) VALUES (NULL) raises 01400 even with a DEFAULT, because explicit NULL overrides defaults. Fix the app to omit the column when the value is absent, or wrap it: NVL(:status, 'new'). DEFAULT ON NULL (12c+) makes the column treat explicit NULLs as omitted — the declarative version of the same fix.
Symptom · 06
Recovered — now prevent the next uncoordinated column
Fix
Gate migrations: any ADD of a NOT NULL column without DEFAULT fails review unless the owning service's INSERT list is attached. Add the CI diff (mandatory columns vs INSERT lists per write path) and an alert on ORA-01400 in the alert log — the first occurrence after a deploy should page within minutes, not after 310 failed orders.
ORA-01400 Causes at a Glance
Root CauseHow to ConfirmFixPrevention
New NOT NULL column, stale INSERT listColumn N/no-default; list omits itAdd DEFAULT or extend the listDEFAULT-or-list-coverage migration rule
Disabled/bypassed populating triggerall_triggers shows DISABLED; bulk path skipsRe-enable; fix path to fire triggersMonitor trigger status; test bulk paths
Missing NEXTVAL on sequence PKINSERT lacks seq.NEXTVAL; PK gets NULLAdd NEXTVAL or migrate to identityIdentity columns for new PKs
Explicit NULL binds over defaultsList includes column with NULL bindOmit-when-null, NVL, or DEFAULT ON NULLDEFAULT ON NULL on ORM-touched columns
Genuinely optional data, wrong constraintBusiness accepts missing valuesRelax to NULLConfirm mandatory-ness with owners first
⚙ Quick Reference
6 commands from this guide
FileCommand / CodePurpose
audit_column_1400.sqlSELECT nullable, data_default, data_typeRead the Three-Part Name in the Message
insert_list_fix.sqlINSERT INTO orders (order_id, customer_id, total, status)The Missing Column in the INSERT List
autopop_1400.sqlSELECT trigger_name, status FROM all_triggersSequences, Identity, and Trigger Defaults
nvl_coalesce_1400.sqlINSERT INTO orders (order_id, customer_id, total, status)NVL/COALESCE
safe_notnull.sqlUPDATE shop.orders SET status = 'new'Backfill Then Constrain
contract_gate_1400.shset -euo pipefailPrevention

Key takeaways

1
01400 names owner, table, column
read NULLABLE and DATA_DEFAULT first.
2
Stale INSERT lists are the top cause; explicit lists plus CI diffs end them.
3
Explicit NULL beats DEFAULT
omit, NVL-wrap, or declare DEFAULT ON NULL.
4
Repair populators (triggers, sequences, identity), don't hand-fill forever.
5
Backfill, default, then constrain
in that order, each step proven.
6
Gate migrations on DEFAULT-or-list-coverage and alert on post-DDL 01400s.

Common mistakes to avoid

5 patterns
×

Adding NOT NULL without DEFAULT to a live table

Symptom
Migration runs clean; every new write from old lists dies with 01400.
Fix
Backfill, declare DEFAULT, then constrain — and attach the service's updated list to the PR.
×

Binding explicit NULLs over defaulted columns

Symptom
DEFAULT exists yet 01400 persists — ORMs bind NULL for every mapped attribute.
Fix
Omit null columns, wrap with NVL, or declare DEFAULT ON NULL.
×

Hand-filling rows while the populator stays broken

Symptom
Incident recurs on the next batch — the disabled trigger still isn't firing.
Fix
Re-enable/repair triggers and NEXTVAL usage; hand-fills are triage, not repair.
×

Using positional INSERTs without column lists

Symptom
Any schema change — nullable or not — shifts positions and corrupts or fails writes.
Fix
Name every column in every INSERT; ban positional form in review.
×

Assuming the payment/app layer caused write failures

Symptom
Failover theater on healthy integrations while the database refuses writes.
Fix
Read app logs for ORA- codes first — the three-part name beats cross-system guessing.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What does ORA-01400 mean?
Q02SENIOR
A column has a DEFAULT but inserts still raise 01400. Why?
Q03SENIOR
How do you add NOT NULL to a populated live table safely?
Q04SENIOR
A trigger-populated column starts 01400ing. Diagnose it.
Q05SENIOR
How do you stop uncoordinated NOT NULL columns in CI?
Q01 of 05JUNIOR

What does ORA-01400 mean?

ANSWER
An INSERT or UPDATE tried to store NULL in a NOT NULL column. The message names schema, table, and column — diagnosis starts at the dictionary with nullability and default.
FAQ · 6 QUESTIONS

Frequently Asked Questions

01
Does a DEFAULT protect against explicit NULL inserts?
02
Why did the migration succeed but writes fail?
03
Should I just drop NOT NULL to stop the errors?
04
Do triggers fire on all load paths?
05
IDENTITY vs sequence+trigger for new PKs?
06
How do I backfill a huge table without locking it?
N
Naren Founder & Principal Engineer

20+ years shipping high-throughput database systems. Drawn from code that ran under real load.

Follow
Verified
production tested
September 23, 2026
last updated
1,905
articles · all by Naren
🔥

That's Oracle. Mark it forged?

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

Previous
ORA-01722 Invalid Number Fix
3 / 5 · Oracle
Next
ORA-02291 Integrity Constraint Fix