Fix Django IntegrityError: UNIQUE, NOT NULL, and Foreign Key Violations
Django IntegrityError means a database write violated a constraint. Here are the 4 most common causes: duplicate unique fields, migration issues, race conditions, missing required fields, and the exact fix for each.
Django throws IntegrityError when a database write violates a constraint. The error is raised at the database level, so it bypasses any model-level validation you have in place.
There are four common causes. Each one has a different fix.
Reading the Error
Three things to read off this:
myapp_useris the database table (app name + model name, lowercase)emailis the column with the UNIQUE constraint- The duplicate value is not shown in the message — you have to find it yourself
Cause 1: Duplicate Value in a Unique Field
Saving two users with the same email triggers IntegrityError. Use get_or_create to avoid the collision:
Or catch the error explicitly:
Fix: Use
get_or_createwhen inserting records that have a unique constraint. It removes the need for a manual existence check.
Cause 2: Migration Added a Unique Constraint to Existing Data
You add unique=True to a field that already has duplicate values. Running python manage.py migrate fails:
Clean up duplicates before applying the migration:
Warning: Delete or merge duplicates first. Running the migration before cleaning up will fail at the database level and cannot be resolved by Django alone.
Cause 3: Race Condition Under Concurrent Requests
Two requests arrive at the same time. Both check whether the email exists, both see nothing, both try to insert. One wins. The other gets IntegrityError.
The fix is to stop using check-then-insert. Let the database enforce uniqueness and catch the error when it fires:
Note: The database unique constraint is the only reliable guard against concurrent inserts. Application-level checks are not atomic.
Cause 4: NOT NULL Constraint on a Required Field
A foreign key or required field is None at save time:
Set the required field before saving:
If the field should be optional at the database level:
Finding the Duplicate Value
The error message does not include the offending value. Find it in the shell:
IntegrityError Types at a Glance
| Error text | Cause | Fix |
|---|---|---|
UNIQUE constraint failed | Duplicate value in unique field | get_or_create or dedup existing data |
NOT NULL constraint failed | Required field is None | Set the field before saving |
FOREIGN KEY constraint failed | Referenced record does not exist | Create the parent record first |
CHECK constraint failed | Value outside allowed range | Check model validators |
FAQ
Q: Why does IntegrityError bypass my model's clean() method?
A: clean() runs during form validation, not during direct ORM saves. If you call Model.objects.create() directly, Django skips full_clean(). Call instance.full_clean() before instance.save() if you want model-level validation on direct saves.
Q: Can I catch IntegrityError for bulk inserts?
A: Yes. Use bulk_create with ignore_conflicts=True to skip duplicates silently. Note that it does not return the existing records, only the ones that were inserted.
For IntegrityError in complex transactions — bulk inserts, signals that trigger saves, or Celery tasks writing concurrently — paste the model and the failing view into DebugAI and it will trace the exact constraint violation.
Debug faster starting today.
Free VS Code extension · 10 sessions/day · no credit card