Fix Django Media Files Not Serving (Uploads Broken in Production)
Troubleshooting guide to fix Django media files not serving in production. Learn how to configure media root, Nginx mappings, and permissions to resolve upload issues.
If your Django app uploads files successfully but:
- Images donβt load
- User uploads return 404
- Media URLs are broken
π Then your media files are not being served correctly
This guide will walk you through how to fix it step-by-step.
β‘ Quick Fix (Try This First)
Run:
sudo systemctl restart gunicorn
sudo systemctl restart nginx
Then check a media file URL:
http://your-domain/media/your-file.jpg
π If still broken, continue below.
π§ Whatβs Happening
In production:
- Django does NOT serve media files
- Nginx must serve them
If uploads are broken, it usually means:
Nginx cannot find or access your media directory
π§ͺ Step-by-Step Diagnosis
Follow these steps in order.
1. Check MEDIA_ROOT setting
In settings.py:
MEDIA_ROOT = '/var/www/myproject/media/'
MEDIA_URL = '/media/'
π This defines where uploaded files are stored
2. Verify files exist
ls /var/www/myproject/media/
You should see:
- Uploaded images/files
π If empty:
- If not, then uploads are not working. Check your upload code.
- Upload process is broken (not Nginx)
3. Test media URL directly
Open in browser:
http://your-domain/media/your-file.jpg
If 404:
- Nginx is not serving media
If works:
- Problem is elsewhere (templates, paths)
4. Check Nginx configuration
Open config:
sudo nano /etc/nginx/sites-available/myproject
or your favorite editor.
Ensure this exists:
location /media/ {
root /var/www/myproject;
}
π Important:
/media/maps to/var/www/myproject/media/
5. Test Nginx config
sudo nginx -t
Then:
sudo systemctl restart nginx
6. Check file permissions
sudo chown -R www-data:www-data /var/www/myproject
sudo chmod -R 755 /var/www/myproject
π Nginx must be able to read media files
π₯ Common Causes (and Fixes)
π΄ MEDIA_ROOT is incorrect
Fix:
MEDIA_ROOT = '/var/www/myproject/media/'
π΄ Nginx not configured for media
Add:
location /media/ {
root /var/www/myproject;
}
π΄ Permissions issue
Fix:
sudo chown -R www-data:www-data /var/www/myproject
π΄ Files stored in wrong location
Check upload path:
Django might be saving elsewhere
π΄ MEDIA_URL incorrect
MEDIA_URL = '/media/'
π§ Debugging Tips
Check Nginx logs
sudo tail -f /var/log/nginx/error.log
Look for:
- 404
- permission denied
Check browser DevTools
- Network tab β failed requests
- Look for:
- 404 errors
- incorrect URLs
Check Django upload path
If using ImageField or FileField:
upload_to='uploads/'
β Quick Fix Checklist
Verify your static files setup and compare it against the full deploy guide so both Nginx mappings stay aligned.
π Related Guides
β FAQ
Whatβs the difference between static and media files?
- Static: CSS, JS (part of your code)
- Media: user uploads (dynamic content)
Can Django serve media files?
Only in development:
DEBUG = True
In production:
π Use Nginx or a CDN to serve media files for better performance and security.
Why do uploads work but files donβt load?
Because:
- Files are saved
- But not served by Nginx
π― Final takeaway
If media files are broken:
Itβs almost always:
- Nginx config
- File permissions
- MEDIA_ROOT mismatch
Fix those, and uploads will work correctly.
If you deploy oftenβ¦
A repeatable, pre-tested setup will save hours of debugging.