# Supabase: “null value in column violates not-null constraint” (23502)

> Supabase error 23502 means an insert or update left a required column empty. Send the value, add a default such as auth.uid(), or fix the trigger.

Canonical: https://app369.com/fix/supabase-null-value-violates-not-null-constraint/
Last updated: 2026-11-09

“null value in column violates not-null constraint” is Postgres error 23502. A row was saved with no value in a required column, and the error names that column. In Supabase it is often a user_id the app never sends, or a sign-up trigger that writes a missing field.

**Short answer**

Find the column in the error, and the Failing row contains line that shows the row. If the app should fill it, send it in the insert. If the database can fill it, add a default, such as default auth.uid() for user_id or default now() for a timestamp. If the error comes from a trigger, fix the trigger. Make a column NOT NULL only after its old rows have values.

Rather not fix it yourself? [**App Fix Ticket**](https://app369.com/fixed-price/flutter-firebase-bug-fix/) starts with a fixed-price diagnosis, then a fixed price for the fix before any fix work.

## **Why the column is empty, and the fix**

1. 01 ### **The insert doesn’t send the column**
  > “If no default value is declared explicitly, the default value is the null value.” [**PostgreSQL docs, Default values**](https://www.postgresql.org/docs/current/ddl-default.html) A column left out of the insert gets its default. With no default, that is null, and a NOT NULL column refuses it.
2. 02 ### **user_id should come from the session** Let the database fill user_id from the signed-in user, so the client can’t forget it or send someone else’s. Keep an RLS policy that checks it. A default only applies when the column is left out: an explicit null still fails, and so does an insert from a signed-out client, because auth.uid() is null. In supabase-js bulk inserts, missing fields become null unless you pass defaultToNull: false.```
alter table public.todos
  alter column user_id set default auth.uid();

-- the client can now insert without user_id
-- supabase.from('todos').insert({ title: 'Buy milk' })
```
3. 03 ### **A sign-up trigger writes a missing field** A trigger on auth.users that copies raw_user_meta_data into a profile writes null when sign-up didn’t send that field. Sign-up then fails with “Database error saving new user”. Use coalesce with a fallback, or allow null in that column.```
insert into public.profiles (id, full_name)
values (new.id, coalesce(new.raw_user_meta_data->>'full_name', ''));
```
4. 04 ### **An update sets the column to null**
  > “A not-null constraint simply specifies that a column must not assume the null value.” [**PostgreSQL docs, Constraints (not-null)**](https://www.postgresql.org/docs/current/ddl-constraints.html) An update or upsert that sends the column as null, for example from an empty form field, fails the same way. Leave the field out of the update when it has no value.
5. 05 ### **Making an old column required**
  > “SET NOT NULL may only be applied to a column provided none of the records in the table contain a NULL value for the column.” [**PostgreSQL docs, ALTER TABLE**](https://www.postgresql.org/docs/current/sql-altertable.html) Adding NOT NULL to a column that already has empty rows fails. Fill them first, then add the constraint.```
update public.todos set status = 'open' where status is null;
alter table public.todos alter column status set not null;
```

Checked against the vendor’s docs on November 9, 2026: [PostgreSQL docs: Constraints (not-null)](https://www.postgresql.org/docs/current/ddl-constraints.html); [PostgreSQL docs: Default values](https://www.postgresql.org/docs/current/ddl-default.html); [PostgreSQL docs: ALTER TABLE](https://www.postgresql.org/docs/current/sql-altertable.html).

## **Rather hand it over?**

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

- [from $450**App Fix Ticket**One reproducible bug in an existing mobile or web app, diagnosed and fixed.**See scope and start**](https://app369.com/fixed-price/flutter-firebase-bug-fix/)
- [from $450**AI-Built App Rescue**A Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.****No issues worth fixing, no charge.**** If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.**See scope and start**](https://app369.com/fixed-price/ai-app-rescue/)

[**All 127 Fiverr reviews**](https://app369.com/reviews/)

Related: [**Supabase violates check constraint**](https://app369.com/fix/supabase-violates-check-constraint/) · [**Supabase “Database error saving new user”**](https://app369.com/fix/supabase-database-error-saving-new-user/) · [**Supabase violates foreign key constraint**](https://app369.com/fix/supabase-violates-foreign-key-constraint/) · [**Supabase new row violates row-level security**](https://app369.com/fix/supabase-new-row-violates-row-level-security/)

Questions

## **More on this error**

<details>

<summary>**Should I just remove NOT NULL? **+</summary>

Only if the column can truly be empty. For a field like user_id, an empty value means a row no one owns, so a default is the better fix.

</details>

<details>

<summary>**Does a default work with RLS? **+</summary>

Yes. The default fills user_id before the policy checks the row, so an insert policy such as with check (auth.uid() = user_id) passes.

</details>

<details>

<summary>**Can you fix it for me? **+</summary>

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.

</details>

A different error?

## **Describe it and get a written quote**

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; Simon replies by email, usually within one business day.

[**Describe your problem **→](https://app369.com/contact/) [**All fixes**](https://app369.com/fix/)