Forums

SECRET_KEY setting must not be empty

I am new to web development so hopefully this is something ridiculously simple. I've been following the Django Girls Tutorial thus far. My goal is to hide the secret key. I tried several different approaches in hopes of getting this to work and have searched these forums with no luck. The only way I can seem to get it to work is by actually putting the hard code secret key in settings.py. I tried setting environment variables in bash shell. Setting the environment variables works when on development local server. I tried calling the env variable in settings.py by adding:

SECRET_KEY=os.environ.get('SECRET_KEY_MYSITE') *** I exported the key as "SECRET_KEY_MYSITE" *** Doing this only gave my the error: raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")

I also tried putting the key in wsgi.py by adding - os.environ["SECRET_KEY"] = "the secret key value". Then calling it in settings.py by - SECRET_KEY = os.getenv('SECRET_KEY'). Same error here: raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.").

I'm sure I'm missing something rather obvious but can't seem to figure it out. In bash I am running environment with Python 3.4 and Django 1.8. I installed whitenoise as well. I've been reading all over the internet that the secret key needs to be hidden so I'm going the extra mile to make sure I get it done. Is hiding the secret key in settings.py here on PA necessary? As of right now I have the secret key in wsgi.py set to *** for security. I appreciate your help! Oh and you have permission to check out the error log.

Hi there,

Environment variables can be a little tricky, because they are set differently in the command line to the actual running wsgi application.

Our recommendation is:

  • Use the postactivate script in ~/.virtualenvs/your-virtualenv/bin to set environment variables for your command-line sessions
  • Use the wsgi file (with os.environ) to set environment variables for the running web application.

It's annoying to have to set them in two places at once. We're thinking about ways to get around that...

Hi Harry,

Thank you for your reply. I'm still not having any luck. Here's what I did:

First Attempt

  1. In myvenv/bin postactivate (this is my current virtual environment) I added export SECRET_KEY_MYSITE= "secret key value"
  2. In wsgi.py added SECRET_KEY_MYSITE=os.environ['SECRET_KEY_MYSITE']
  3. In settings.py added SECRET_KEY = os.environ.get('SECRET_KEY_MYSITE', '')

Second Attempt

  1. Same thing as 1st attempt but added SECRET_KEY_MYSITE= "secret key value" in .virtualenvs/ postactivate instead of in myvenv/bin

Third Attempt

Removed what I did in wsgi.py in previous attempts. Also removed what I did in .virtualenvs/ postactivate. At this point I have my export statement in myvenv/bin and calling os.environ in settings.py.

Am I missing something? echo $SECRET_KEY_MYSITE works in bash. I have virtual environment set in PA's "Web" tab to: /home/isaac2016/my-first-blog/myvenv/ . Everything else works great!

Thank you for your help.

You're almost there, but at step 2, when you're setting the environment variable in your wsgi file, you have to set it into the environment (duplicating the value in the postactivate script), rather than trying to retrieve it. So you should have a line like this:

os.environ["SECRET_KEY_MYSITE"] = "secret key value"

Back in postactivate, make sure there are no spaces:

SECRET_KEY_MYSITE="secret key value"

Hi Harry,

...no luck. Here's what I have:

Postactivate in home/isaac2016/my-project/myvenv/bin/. I made sure no spaces and tried setting the variable using "export" as well as removing it.

 1. export SECRET_KEY_MYSITE="secret key value"

wsgi.py

 2.os.environ["SECRET_KEY_MYSITE"] ="secret key value"

settings.py tried this with os.environ.get and getenv...nothing

 3. SECRET_KEY=os.environ("SECRET_KEY_MYSITE")

I made sure to reload the server everytime a change was made.

are you sure it's not SECRET_KEY=os.environ["SECRET_KEY_MYSITE"]

In settings.py I changed this:

SECRET_KEY=os.environ("SECRET_KEY_MYSITE")

to this:

 SECRET_KEY=os.environ["SECRET_KEY_MYSITE"]

Still no luck. I get this error: raise KeyError(key) from None

2015-12-11 18:25:52,536 :KeyError: 'SECRET_KEY_MYSITE'

Also, how is placing the security key in WSGI any more secure than it being in settings.py? Do we add WSGI to .gitignore? Thank you for your help.

Ah, I think the problem is that you and Conrad are talking about different WSGI files. You need to put the os.environ stuff in the WSGI file that's linked from the "Web" tab, near the top. That one is outside your repository (it's stored in /var/www, so it should be reasonably secure.

Ha! That was it! ...of course, it would be the wrong file. Thank you everyone for your help!

Yay! Thanks for confirming, I'm glad we got there in the end.

Hi! This topic wroked for me. Still up-to-date

Hi, I've folowed the steps described here but I still end up with this error :

 File "/home/omnicord/omnicord_market/OMNICORD_MARKET/OMNICORD_MARKET/settings.py", line 23, in <module>
    SECRET_KEY = os.environ['SECRET_KEY_OMNICORD']
 File "/home/omnicord/.virtualenvs/OmniEnv/lib/python3.6/os.py", line 669, in __getitem__
    raise KeyError(key) from None
KeyError: 'SECRET_KEY_OMNICORD'

In the web app tab's wsgi file i have set :

os.environ['SECRET_KEY_OMNICORD']="secret key value"

In postactivate in my virtualenv :

SECRET_KEY_OMNICORD="secret key value"

and in settings.py :

SECRET_KEY = os.environ['SECRET_KEY_OMNICORD']

Am i missing something ?

Are you getting that error in a console? I don't see anything like that in the website logs.

If it is in a console, did you start the console and workon the virtualenv before you added the code to the postactivate script, perhaps? It might be that you just need to start a new console inside the virtualenv using the link on the "Web" tab, and try again there.

Yes you're right, I was doing exactly that. But after closing it and retrying the same error still occurs :(

Also i tried switching os.environ['SECRT_KEY_OMNICORD'] to os.environ.get('SECRET_KEY_OMNICORD') in settings.py and the error is "secret key can't be empty". All of this happens when i'm trying to collect static files, wich also gives me a key error :

(OmniEnv) 14:23 ~/omnicord_market/OMNICORD_MARKET (master)$ python manage.py collectstatic
Traceback (most recent call last):
  File "/home/omnicord/.virtualenvs/OmniEnv/lib/python3.6/site-packages/django/core/management       /__init__.py", line 204, in fetch_command
app_name = commands[subcommand]
KeyError: 'collectstatic'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "manage.py", line 15, in <module>
execute_from_command_line(sys.argv)
File "/home/omnicord/.virtualenvs/OmniEnv/lib/python3.6/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
utility.execute()
File "/home/omnicord/.virtualenvs/OmniEnv/lib/python3.6/site-packages/django/core/management/__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
 File "/home/omnicord/.virtualenvs/OmniEnv/lib/python3.6/site-packages/django/core/management/__init__.py", line 211, in fetch_command
settings.INSTALLED_APPS
File "/home/omnicord/.virtualenvs/OmniEnv/lib/python3.6/site-packages/django/conf/__init__.py", line 57, in __getattr__
self._setup(name)
File "/home/omnicord/.virtualenvs/OmniEnv/lib/python3.6/site-packages/django/conf/__init__.py", line 44, in _setup
self._wrapped = Settings(settings_module)
File "/home/omnicord/.virtualenvs/OmniEnv/lib/python3.6/site-packages/django/conf/__init__.py", line 126, in __init__
raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")
django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.

maybe they're both linked to the same issue ? Thanks for your help

Yes, that sounds like it's the same problem. It sounds very much like the SECRET_KEY_OMNICORD environment variable isn't getting set. What happens if you run

echo $SECRET_KEY_OMNICORD

in the bash console? Also, do you see SECRET_KEY_OMNICORD mentioned in the output if you run the env command?

echo $SECRET_KEY_OMNICORD returns the value I entered as the secret key. But what do you mean by running the env command ?

By running the env command I just meant, type env into a bash console then hit return.

But the fact that you get the value you entered as the secret key when you ran the echo command gives us the same information; the environment variable is definitely being set correctly. So it's very confusing that it's not able to find it in settings.py!

Here's an experiment we could try. Just before the line in the settings where you have this:

os.environ.get('SECRET_KEY_OMNICORD')

...could you add this:

print(os.environ.keys())

...and try running collectstatic again, and let us know what it prints out? What I would expect is that before the traceback, it will show a list of all of the environment variables that it can see, so we can check to see if SECRET_KEY_OMNICORD is in there.

Ok, i added the print line as you suggested and the secret key variable is not in the list. Actually, none of the variables i added in wsgi are in the list, except for the first one "DJANGO_SETTINGS_MODULE". I don't see any difference in the writing of those lines. Thx again for your time...

If you're running in a bash console, you'll only get the ones that you've specified in the virtualenv postactivate script -- not the ones from the WSGI file (which is only used in the context of a running website).

But still, you are defining the SECRET_KEY_OMNICORD variable in your postactivate, so it should be present. Here's another experiment -- right now, I think you have something like this in postactivate

SECRET_KEY_OMNICORD="something"

Could you adding "export " at the start, so that it looks like this:

export SECRET_KEY_OMNICORD="something"

...then start a new Bash console, workon the virtualenv, and then try collectstatic again?

Ho yes it's working ! Thank you very much for your help !

Excellent, thanks for confirming! We've updated the relevant help page.

File "/home/anbj1/.virtualenvs/env/lib/python3.6/site-packages/django/conf/init.py", line 126, in init raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.") django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.

I made some changes to my model, but now i want to migrate, when i migrate on virualenv, i am getting the error.

seems like you also posted here. will respond there

"Ah, I think the problem is that you and Conrad are talking about different WSGI files. You need to put the os.environ stuff in the WSGI file that's linked from the "Web" tab, near the top. That one is outside your repository (it's stored in /var/www, so it should be reasonably secure." - conrad

Thanks for that info, I could not think for the life of me why it wasn't working. Totally forgot there are 2 WSGI files. Hopefully this will help other people.

Glad we could help!

I followed comments above but still get error KEYERROR

Are you actually using the environment variable in your settings?

Thank you for this post... It solved all of my problems regarding loading up my environment variables...

Still relevant topic :) I'm having troubles despite following guidance as tightly as I could. My problem is with running Django commands on schedule, but the core - echo $SECRET_KEY does not return a key (I get an empty line in Bash). Eventually, I get this error when I run a task with a command: django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty.

I take it my .env is working fine as my website is running. I have a line SECRET_KEY=******* in there. What should be in my postactivate file? I have set -a; source ~/myccount/myproject/.env; set +a Is this correct?

Where do you set it? Is it in the scheduled task command?

Yes, it is in scheduled tasks on PA

Are you sure you're putting the environment code in the postactivate for the correct virtualenv?