Fix 404 Not Found: GET /static/css/styles.css HTTP/1.1 404 Not Found in Django
This error means Django cannot serve the requested static file because it is not collected or the static files configuration is incorrect. Fix it by running collectstatic, verifying STATIC_URL and STATIC_ROOT in settings, ensuring the file exists in the correct app's static/ directory, and using {% static %} template tags.
Reading the Stack Trace
Here's what each line means:
- File "/venv/lib/python3.11/site-packages/django/contrib/staticfiles/views.py", line 36, in serve: Django's static file server is looking for the file in the STATIC_ROOT directory.
- File "/venv/lib/python3.11/site-packages/django/views/static.py", line 44, in serve: The file was not found at the expected path. It either was not collected or does not exist.
- raise Http404('"%(path)s" does not exist': Django returns a 404 because the static file is missing from the collected static files directory.
Common Causes
1. collectstatic not run
The static files have not been collected to STATIC_ROOT, which is required for production deployments.
# settings.py
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
# Never ran: python manage.py collectstatic
2. Wrong directory structure for app static files
Static files are placed in the app root instead of the app's static/ subdirectory.
# File at: myapp/styles.css (WRONG)
# Should be: myapp/static/myapp/styles.css
# template.html
<link rel="stylesheet" href="{% static 'myapp/styles.css' %}">
3. Hardcoded static URL instead of template tag
The template hardcodes the static URL path instead of using Django's {% static %} tag, which breaks when STATIC_URL changes.
<!-- template.html -->
<link rel="stylesheet" href="/static/css/styles.css">
<!-- Breaks when STATIC_URL is changed to a CDN URL -->
The Fix
Use the {% static %} template tag instead of hardcoding URLs. Configure STATICFILES_DIRS to include your project-level static directory, set STATIC_ROOT for collectstatic output, and run collectstatic before deploying.
<!-- template.html -->
<link rel="stylesheet" href="/static/css/styles.css">
<script src="/static/js/app.js"></script>
<!-- template.html -->
{% load static %}
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
<script src="{% static 'js/app.js' %}"></script>
# settings.py
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATICFILES_DIRS = [
BASE_DIR / 'static',
]
# Run collectstatic:
# python manage.py collectstatic --noinput
Testing the Fix
import pytest
from django.test import TestCase, Client
from django.contrib.staticfiles import finders
class TestStaticFiles(TestCase):
def test_css_file_exists(self):
result = finders.find('css/styles.css')
assert result is not None, 'css/styles.css not found by static finders'
def test_js_file_exists(self):
result = finders.find('js/app.js')
assert result is not None, 'js/app.js not found by static finders'
def test_template_uses_static_tag(self):
client = Client()
response = client.get('/')
assert response.status_code == 200
content = response.content.decode()
assert '/static/css/styles.css' in content or 'styles.css' in content
def test_static_file_is_served(self):
client = Client()
response = client.get('/static/css/styles.css')
assert response.status_code == 200
Run your tests:
pytest
Pushing Through CI/CD
git checkout -b fix/static-files-not-found,git add templates/ settings.py static/,git commit -m "fix: use static template tag and configure staticfiles correctly",git push origin fix/static-files-not-found
Your CI config should look something like this:
name: CI
on:
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip'
- run: pip install -r requirements.txt
- run: python manage.py collectstatic --noinput
- run: pytest --tb=short -q
The Full Manual Process: 18 Steps
Here's every step you just went through to fix this one bug:
- Notice the error alert or see it in your monitoring tool
- Open the error dashboard and read the stack trace
- Identify the file and line number from the stack trace
- Open your IDE and navigate to the file
- Read the surrounding code to understand context
- Reproduce the error locally
- Identify the root cause
- Write the fix
- Run the test suite locally
- Fix any failing tests
- Write new tests covering the edge case
- Run the full test suite again
- Create a new git branch
- Commit and push your changes
- Open a pull request
- Wait for code review
- Merge and deploy to production
- Monitor production to confirm the error is resolved
Total time: 30-60 minutes. For one bug.
Or Let bugstack Fix It in Under 2 minutes
Every step above? bugstack does it automatically.
Step 1: Install the SDK
pip install bugstack
Step 2: Initialize
import bugstack
bugstack.init(api_key=os.environ["BUGSTACK_API_KEY"])
Step 3: There is no step 3.
bugstack handles everything from here:
- Captures the stack trace and request context
- Pulls the relevant source files from your GitHub repo
- Analyzes the error and understands the code context
- Generates a minimal, verified fix
- Runs your existing test suite
- Pushes through your CI/CD pipeline
- Deploys to production (or opens a PR for review)
Time from error to fix deployed: Under 2 minutes.
Human involvement: zero.
Try bugstack Free →No credit card. 5-minute setup. Cancel anytime.
Deploying the Fix (Manual Path)
- Run collectstatic locally and verify all files are present.
- Open a pull request with the template and settings fixes.
- Wait for CI checks including collectstatic to pass.
- Have a teammate review and approve the PR.
- Merge to main and verify static files load correctly in staging.
Frequently Asked Questions
BugStack runs collectstatic, verifies all referenced static files exist, runs your test suite, and validates that templates load correctly before marking it safe to deploy.
BugStack never pushes directly to production. Every fix goes through a pull request with full CI checks, so your team can review it before merging.
No. Add staticfiles/ to .gitignore and run collectstatic as part of your deployment pipeline. The collected files are a build artifact, not source code.
Use WhiteNoise middleware for simple setups, or configure your web server (Nginx/Apache) to serve STATIC_ROOT directly. Never use Django's development server to serve static files in production.