Setting DEBUG = False causes 500 Error

171,679

Solution 1

Django 1.5 introduced the allowed hosts setting that is required for security reasons. A settings file created with Django 1.5 has this new section which you need to add:

# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.9/ref/settings/#allowed-hosts
ALLOWED_HOSTS = []

Add your host here like ['www.beta800.net'] or ['*'] for a quick test, but don't use ['*'] for production.

Solution 2

I know this is late but I ended up here with a search for my error 500 with DEBUG=False, in my case it did turn out to be the ALLOWED_HOSTS but I was using os.environ.get('variable') to populate the hosts, I did not notice this until I enabled logging, you can log all errors to file with the below and it will log even when DEBUG=False:

# settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
            'datefmt' : "%d/%b/%Y %H:%M:%S"
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': 'mysite.log',
            'formatter': 'verbose'
        },
    },
    'loggers': {
        'django': {
            'handlers':['file'],
            'propagate': True,
            'level':'DEBUG',
        },
        'MYAPP': {
            'handlers': ['file'],
            'level': 'DEBUG',
        },
    }
}

Solution 3

I encountered the same issue just recently in Django 2.0. I was able to figure out the problem by setting DEBUG_PROPAGATE_EXCEPTIONS = True. See here: https://docs.djangoproject.com/en/2.0/ref/settings/#debug-propagate-exceptions

In my case, the error was ValueError: Missing staticfiles manifest entry for 'admin/css/base.css'. I fixed that by locally running python manage.py collectstatic.

Solution 4

In my case, reading docs of third party apps properly saved me.

The culprit? django_compressor

I had

{% load compress %}
{% compress css %}
 ... css files linked here ..
{% endcompress %}

DEBUG = True always gave me 500. To fix it, I needed a line in my settings to get it running

COMPRESS_ENABLED = os.environ.get('COMPRESS_ENABLED', False)

Solution 5

Right, in Django 1.5 if DEBUG = False, configure ALLOWED_HOSTS, adding domains without the port number. example:

ALLOWED_HOSTS = ['localhost']
Share:
171,679
zhiguo.wang
Author by

zhiguo.wang

Updated on July 12, 2022

Comments

  • zhiguo.wang
    zhiguo.wang almost 2 years

    Once I change the DEBUG = False, my site will generate 500 (using wsgi & manage.py runserver), and there is no error info in Apache error log and it will run normally when I change debug to True .

    I'm using Django 1.5 & Python 2.7.3 here is Apache access log and without any log in apache error log

    www.beta800.net:80 222.247.56.11 - - [28/Feb/2013:13:42:28 +0800] "GET / HTTP/1.1" 500 257 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22"
    www.beta800.net:80 222.247.56.11 - - [28/Feb/2013:13:42:28 +0800] "GET /favicon.ico HTTP/1.1" 500 257 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22"
    www.beta800.net:80 222.247.56.11 - - [28/Feb/2013:13:42:28 +0800] "GET /favicon.ico HTTP/1.1" 500 257 "-" "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.97 Safari/537.22"
    

    Here is my settings file:

    import os.path    
    DEBUG = False 
    #TEMPLATE_DEBUG = DEBUG
    
    HERE = os.path.dirname(__file__)
    ADMINS = (
        ('admin', '[email protected]'),
    )
    
    MANAGERS = ADMINS
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
            'NAME': 'zdm',                      # Or path to database file if using sqlite3.
            'USER': 'root',                      # Not used with sqlite3.
            'PASSWORD': 'passwd',                  # Not used with sqlite3.
            'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
            'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
        }
    }
    
    # Local time zone for this installation. Choices can be found here:
    # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
    # although not all choices may be available on all operating systems.
    # In a Windows environment this must be set to your system time zone.
    TIME_ZONE = 'America/Chicago'
    
    # Language code for this installation. All choices can be found here:
    # http://www.i18nguy.com/unicode/language-identifiers.html
    LANGUAGE_CODE = 'en-us'
    
    SITE_ID = 1
    
    # If you set this to False, Django will make some optimizations so as not
    # to load the internationalization machinery.
    USE_I18N = True
    
    # If you set this to False, Django will not format dates, numbers and
    # calendars according to the current locale.
    USE_L10N = True
    
    # If you set this to False, Django will not use timezone-aware datetimes.
    USE_TZ = True
    
    # Absolute filesystem path to the directory that will hold user-uploaded files.
    # Example: "/home/media/media.lawrence.com/media/"
    MEDIA_ROOT = ''
    
    # URL that handles the media served from MEDIA_ROOT. Make sure to use a
    # trailing slash.
    # Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
    MEDIA_URL = ''
    
    # Absolute path to the directory static files should be collected to.
    # Don't put anything in this directory yourself; store your static files
    # in apps' "static/" subdirectories and in STATICFILES_DIRS.
    # Example: "/home/media/media.lawrence.com/static/"
    #STATIC_ROOT = os.path.join(HERE, 'static').replace('\\','/')
    
    # URL prefix for static files.
    # Example: "http://media.lawrence.com/static/"
    STATIC_URL = '/static/'
    #STATIC_ROOT = os.path.join(HERE, 'static').replace('\\','/')
    S= os.path.join(HERE, 'static').replace('\\','/')
    
    # Additional locations of static files
    STATICFILES_DIRS = (
        # Put strings here, like "/home/html/static" or "C:/www/django/static".
        # Always use forward slashes, even on Windows.
        # Don't forget to use absolute paths, not relative paths.
        '/home/zdm/static',
    )
    
    # List of finder classes that know how to find static files in
    # various locations.
    STATICFILES_FINDERS = (
        'django.contrib.staticfiles.finders.FileSystemFinder',
        'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    #    'django.contrib.staticfiles.finders.DefaultStorageFinder',
    )
    
    # Make this unique, and don't share it with anybody.
    SECRET_KEY = '9a7!^gp8ojyk-^^d@*whuw!0rml+r+uaie4ur$(do9zz_6!hy0'
    
    # List of callables that know how to import templates from various sources.
    TEMPLATE_LOADERS = (
        'django.template.loaders.filesystem.Loader',
        'django.template.loaders.app_directories.Loader',
    #     'django.template.loaders.eggs.Loader',
    )
    
    MIDDLEWARE_CLASSES = (
        'django.middleware.common.CommonMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        # Uncomment the next line for simple clickjacking protection:
        # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
    )
    
    ROOT_URLCONF = 'zdm.urls'
    
    # Python dotted path to the WSGI application used by Django's runserver.
    WSGI_APPLICATION = 'zdm.wsgi.application'
    
    TEMPLATE_DIRS = (
        # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
        # Always use forward slashes, even on Windows.
        # Don't forget to use absolute paths, not relative paths.
        '/home/zdm/templates',
    )
    
    INSTALLED_APPS = (
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.sites',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        # Uncomment the next line to enable the admin:
        'django.contrib.admin',
        # Uncomment the next line to enable admin documentation:
        # 'django.contrib.admindocs',
        'zdm',
        'portal',
        'admin',
        'tagging',
    )
    
  • shreddd
    shreddd over 11 years
    Wow - this bit us hard. It really sucks that this setting is buried in the docs. Our production site wouldn't work with DEBUG = False. Thank you for pointing this out!!!
  • gertvdijk
    gertvdijk about 11 years
    More on the security issues that introduced this setting: Practical HTTP Host header attacks. Will definitely convince you not to use ['*'] in production.
  • hwjp
    hwjp about 11 years
    bl. annoying that they don't even stick it in as a default value in settings.py, perhaps with an expanatory comment...
  • maazza
    maazza about 11 years
    just use reverse and url tag and you should be fine
  • Admin
    Admin over 10 years
    my gunicorn config file is as follows: #!/bin/bash cd /var/web/delicms_env/deli_cms/ source ../bin/activate exec gunicorn --workers=3 deli_cms.wsgi:application
  • Admin
    Admin over 10 years
    my problem is now solved, I was using the gunicorn_django script and it was giving me deprecated messages. Still not sure why it worked locally, didn't change my nginx config just changed the old script to use gunicorn and use the wsgi:application module instead and it works again. Gunicorn was throwing some deprecation messages before this as well but nothing specific to my issue.
  • binithb
    binithb over 10 years
    i had exactly the same hilarious pattern !, except that it became hilarious only after I found this, thanks. before that it was just plain frustrating
  • binithb
    binithb over 10 years
    If your settings file comes from a django 1.5 installation, the configuration ALLOWED_HOSTS will be there, with an explanatory comment (like what @hwjp wanted). If you add your own entry of ALLOWED_HOSTS (and have an existing , duplicated ALLOWED_HOSTS ) you will continue to get 500 error .
  • nicorellius
    nicorellius over 10 years
    Something that helps in all this is to use a local_settings.py for each environment and then import it in settings.py.
  • mephisto
    mephisto over 10 years
    what i like to do, is have a settings/ directory instead of a settings.py. In this directory, you can have separate .py files for different environments, and a base.py for general settings. Production dependant settings can then start by importing * from the base settings, and just override whatever they need to override. Also, the required init.py needed to turn that settings/ directory into a valid module, can first import from base.py, and then try to import from a local.py (which would only exist locally). that would mean you don't need to specify local settings manually
  • StefanNch
    StefanNch about 10 years
    Sometimes I wonder why Django is becoming more and more frustrating to work with! Surelly those guys are much better programmers than me, but I really don't understand the decision to "fix" vulnerabilities at the application level, when the real and clean move would be to configure the server properly. Same goes for "template caching" and "persistent connections" ... Useless code that will never be used in a serious website; still is presented as the holy grail of programming! Maybe is just me, I've been wrong before!
  • Ivan P
    Ivan P almost 10 years
    So another funny thing is that it matters where in the settings file you define ALLOWED_HOSTS. Put it in the beginning - the error persisted. Moved to the end of the file - worked!
  • Ali Raza Bhayani
    Ali Raza Bhayani over 9 years
    This solved my problem. This Blog post shows a detailed description of the error and solution. I had my server IP which I entered in the ALLOWED_HOSTS list to get rid of 500 error.
  • ecoe
    ecoe over 9 years
    setting DEBUG=False can unveil import errors as well: stackoverflow.com/questions/25676453/…
  • BlakePetersen
    BlakePetersen about 9 years
    For whatever reason, using 'localhost' didn't work for me. I had to use the IP '127.0.0.1' instead. I was also able to use '*' if you're freaking out and just want it to work. I wouldn't advise doing that in production, however. OSX running Django 1.4.20
  • krischan
    krischan over 8 years
    This was my issue also, the base template that the custom 404 page was referencing used the static tag but did not include the {% load static %} at the top. I didn't notice it elsewhere because my other templates had this line but makes sense to put it in the base anyhow as it refers to static files all over the place.
  • amchugh89
    amchugh89 over 8 years
    even the css and js stuff?
  • amchugh89
    amchugh89 over 8 years
    even links to js and css assets?
  • amchugh89
    amchugh89 over 8 years
    ALLOWED_HOSTS is NOT the only issue, for me I had to make a 404.html and put it in the base level of my templates (not app level) - Also, you can make a 404 view and add a 404handler url but I think thats optional. 404.html fixed it
  • webzy
    webzy over 8 years
    @amchugh89: no, just "django" URLs
  • amchugh89
    amchugh89 over 8 years
    My issue is that whitenoise wasn't able to find some image and was throwing ValueError. I also couldn't find it, but didn't know how to tell whitenoise not to look for it. So I turned whitenoise off, use the django static serve and now I can run debug=False in prod. Obviously not ideal :(
  • Pieter
    Pieter over 8 years
    I set ALLOWED_HOSTS to ['*'] for testing purposes and still got a 500 after rebooting the server. No sign of trouble in the server log, only that damned HTTP 500. How do I obtain more error information without relying on DEBUG = True?
  • Pieter
    Pieter over 8 years
    Nevermind, found the problem. It was related to django-pipeline's behavior when the static hasn't been collected yet. As a general tip, placing a breakpoint in Django's handle_uncaught_exception method will help you figure out what's going on here.
  • Stefan Dragnev
    Stefan Dragnev about 8 years
    This should be the accepted answer. It's much more useful to simply ask the framework itself what is wrong after using the production settings, instead of trying to guess.
  • Phil Gyford
    Phil Gyford almost 8 years
    Same solution here - I was using static to include a CSS file that didn't exist.
  • Eugene Pakhomov
    Eugene Pakhomov almost 8 years
    I had the same problem with whitenoise. python manage.py collectstatic fixed it.
  • Rob
    Rob over 7 years
    Indeed, this is not something to wander around in the dark about. Just look at the error message you would normally see using this method. In my case, I was missing a different setting in my settings.py that my app was looking for. All I needed was the log to track this down. One important note: I added /path/to/my/django/ before the 'mysite.log' as shown in the docs example: docs.djangoproject.com/en/1.10/topics/logging/#examples
  • Stack
    Stack over 6 years
    I have spent hours looking for a solution, no use. according to this answer just use logging and you should have your problem, this is the best answer. Thanks OP!
  • Nick
    Nick over 6 years
    How does this answer the original question?
  • Fanckush
    Fanckush over 6 years
    Thanks that was the reason it didn't work for me, but doesn't that line disable django_compressor from doing its job?
  • KhoPhi
    KhoPhi over 6 years
    @Fanckush Nope. No harm is involved. django-compressor.readthedocs.io/en/latest/settings/… Compressor would still be doing its job perfectly! Simply compress all your statics (like css), so that setting is thus useless as your assets are already compressed
  • Deepak Sharma
    Deepak Sharma about 6 years
    @amchungh89 you are a life saver! Thanx for pointing that out.
  • harmv
    harmv about 6 years
    Why is this marked the correct answer? An incorrect ALLOWED_HOSTS gives a server 400 error, not a server 500.
  • Kavi Vaidya
    Kavi Vaidya over 5 years
    I go the same thing but collectstatic did not fix it for me. Did you get a "can't be reached error"? In that case, how did you fix it?
  • cammil
    cammil over 5 years
    My server errors do not seem to produce any logs! I have tried various logging configs to no avail. Any ideas?
  • João Victor Oliveira
    João Victor Oliveira over 5 years
    @Pieter how did you fix your issue? I had the exact same problem. When I remove the static reference, I don't get the error anymore
  • Pieter
    Pieter over 5 years
    I don't recall, I'd need a time machine to ask myself... The breakpoint in Django's handle_uncaught_exception method still sounds like a useful trick though!
  • themessup
    themessup about 5 years
    Thank you! This solved my error. Turns out I needed to run collectstatic to collect some static assets from a package.
  • burney
    burney over 4 years
    I think 'FALSE' is a string, so it's equal to True, that's why it does not get an error.
  • TheHippo
    TheHippo about 3 years
    Why is this so far down? This helps no matter what the reason for the error is.
  • Gorgonzola
    Gorgonzola about 3 years
    I added this to my settings and it tells me it wont run because of not having permission to access the log. I gave the permissions I even changed ownership of the log to root. I commented out this logging script but nothing. PermissionError: [Errno 13] Permission denied: '/mysite.log' ValueError: Unable to configure handler 'file'
  • squareborg
    squareborg about 3 years
    @Gorgonzola There could be a number of reasons why you get permission denied, Start with is the python application running as the user your expecting | ./mysite.log is a relative path is your PWD where you think it is. Is there some security blocking it such as SELINUX
  • Gorgonzola
    Gorgonzola about 3 years
    @squareborg I tried figuring it out but nothing. Since I am developing I had the luxury of just loading a previous version and moved on. I gave permission to everything, erased the code. Tried to clear the tracks so to speak but it kept asking for access to that logfile which I touched and gave permissions just in case. It was a weird one, I could not say for sure.
  • squareborg
    squareborg about 3 years
    @Gorgonzola if you have a sys admin in your team holla at them. They are best at troubleshooting permission denied. Like I say there's a lot of things that can get in the way.
  • MjZac
    MjZac about 3 years
    Wow! thanks for saving time. I had a static tag pointing to non existing file and was throwing 500 on Debug=False.
  • xax
    xax almost 3 years
    Changing to this - whitenoise.storage.CompressedStaticFilesStorage - worked for me.
  • Dt23
    Dt23 over 2 years
    This should be the answer to the question "How do I debug a 500 error in Django".
  • Daniel Donnelly
    Daniel Donnelly over 2 years
    Where does mysite.log get placed? It's not in the root directory of my project on Heroku using heroku run ls.
  • Dekriel
    Dekriel over 2 years
    this was the most hilarious problem I have ever had. Quizzed me for 2 hours straight.
  • pspahn
    pspahn over 2 years
    While I still have some other things to figure out and fix, this seems like it was the answer for me. One of these days I will fully understand how static files work in production. I don't know why it confuses me so much.
  • Tyler A.
    Tyler A. about 2 years
    Note that according to the document linked in the answer, this shouldn't be enabled in production (without a complete understanding of what it does).