Debugging WSGI “Truncated or Oversized Response Headers” Error in Django/Apache2 Deployment


2 views

Recently while debugging a Django 1.10 application running on Apache2/Ubuntu 16.04, I encountered a particularly stubborn WSGI error:

[wsgi:error] Truncated or oversized response headers received from daemon process

The symptoms were:

  • Apache error logs flooded with WSGI header size warnings
  • Cloudflare intermittently showing 502 errors
  • Django debug logs completely silent (despite debug=True)
  • Static files served normally while dynamic requests failed

After eliminating common suspects like large file uploads (which wasn't our case), I discovered the root cause was excessive cookie data being set in responses. WSGI has strict limits on header sizes (typically 8KB), and Django's session middleware can easily exceed this with:

# Problematic session data example
request.session['large_dataset'] = json.dumps(huge_object)  # Could be > 8KB

To confirm this was the issue, I created a test middleware:

class HeaderSizeMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        
    def __call__(self, request):
        response = self.get_response(request)
        header_size = sum(len(k) + len(v) for k,v in response.items())
        print(f"Headers size: {header_size} bytes")
        return response

This revealed responses with 12KB+ headers in some cases.

Apache Configuration

Increase WSGI buffer limits in Apache configuration:

WSGIBufferSize 16384
WSGIResponseBufferSize 16384

Django Optimizations

1. Reduce session data size:

# Instead of storing entire objects
request.session['optimized_data'] = {'id': obj.id}  # Store references only

2. Configure session serialization:

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'

Alternative Solutions

For API responses, consider switching to token-based authentication to eliminate cookie headers entirely.

After applying these changes, I verified using:

curl -I http://localhost | grep -i content-length

And monitoring Apache logs for any residual WSGI warnings.


When your Apache server suddenly starts throwing "Truncated or oversized response headers" errors from Django's WSGI process, it can be particularly frustrating because:

  • Django's debug logs show nothing unusual
  • Static files continue serving normally
  • The Django shell works perfectly
  • Errors appear intermittently (502 from Cloudflare, 500 from server)

Based on the error pattern you described, here are the key areas to investigate:

# Check your Apache WSGI configuration
WSGIDaemonProcess example.org python-home=/path/to/venv python-path=/path/to/project
WSGIProcessGroup example.org
WSGIApplicationGroup %{GLOBAL}
WSGIPassAuthorization On
WSGIRestrictStdout Off

Add these directives to your Apache virtual host configuration:

# Increase header buffer sizes
LimitRequestFieldSize 16380
LimitRequestLine 16380

# WSGI-specific timeouts
WSGIDaemonProcess example.org \
    processes=4 \
    threads=15 \
    display-name=example-org \
    inactivity-timeout=300 \
    request-timeout=300 \
    socket-timeout=300 \
    header-timeout=300 \
    connect-timeout=300

Create a test view to isolate the issue:

# views.py
from django.http import HttpResponse
import sys

def wsgi_debug(request):
    response = HttpResponse("WSGI Debug Output")
    response['X-WSGI-Debug'] = 'Testing header limits'
    response['X-Python-Version'] = sys.version
    response['X-WSGI-Version'] = sys.version_info[0]
    return response

Check these specific areas in your Django project:

# settings.py
# Disable DEBUG in production!
DEBUG = False

# Check middleware ordering
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # ... other middleware
]

# Check ALLOWED_HOSTS
ALLOWED_HOSTS = ['example.org', 'www.example.org']

When basic checks don't reveal the issue:

  1. Run Apache in foreground mode: apachectl -X
  2. Enable WSGI verbose logging: WSGIVerboseDebugging On
  3. Check for memory leaks in your Python packages
  4. Test with a minimal WSGI application to rule out Django issues

After making changes:

# Validate Apache config
sudo apachectl configtest

# Restart services properly
sudo systemctl restart apache2

# Clear any cached WSGI processes
sudo pkill -f wsgi