[ruby-on-rails] How to solve error "Missing `secret_key_base` for 'production' environment" (Rails 4.1)

I created a Rails application, using Rails 4.1, from scratch and I am facing a strange problem that I am not able to solve.

Every time I try to deploy my application on Heroku I get an error 500:

Missing `secret_key_base` for 'production' environment, set this value in `config/secrets.yml`

The secret.yml file contains the following configuration:

secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>

On Heroku I configured the "SECRET_KEY_BASE" environment variable with the result of the rake secret command. If I launch heroku config, I can see the variable with the correct name and value.

Why am I still getting this error?

This question is related to ruby-on-rails ruby heroku ruby-on-rails-4

The answer is


I have a patch that I've used in a Rails 4.1 app to let me continue using the legacy key generator (and hence backwards session compatibility with Rails 3), by allowing the secret_key_base to be blank.

Rails::Application.class_eval do
  # the key_generator will then use ActiveSupport::LegacyKeyGenerator.new(config.secret_token)
  fail "I'm sorry, Dave, there's no :validate_secret_key_config!" unless instance_method(:validate_secret_key_config!)
  def validate_secret_key_config! #:nodoc:
    config.secret_token = secrets.secret_token
    if config.secret_token.blank?
      raise "Missing `secret_token` for '#{Rails.env}' environment, set this value in `config/secrets.yml`"
    end 
  end 
end

I've since reformatted the patch are submitted it to Rails as a Pull Request


You can export the secret keys to as environment variables on the ~/.bashrc or ~/.bash_profile of your server:

export SECRET_KEY_BASE = "YOUR_SECRET_KEY"

And then, you can source your .bashrc or .bash_profile:

source ~/.bashrc 
source ~/.bash_profile

Never commit your secrets.yml


For rails6, I was facing the same problem, as I was missing following files, once I added them, the issue resolved:

1. config/master.key
2. config/credentials.yml.enc

Make sure you have this files.!!!


On Nginx/Passenger/Ruby (2.4)/Rails (5.1.1) nothing else worked except:

passenger_env_var in /etc/nginx/sites-available/default in the server block.

Source: https://www.phusionpassenger.com/library/config/nginx/reference/#passenger_env_var


Demi Magus answer worked for me until Rails 5.

On Apache2/Passenger/Ruby (2.4)/Rails (5.1.6), I had to put

export SECRET_KEY_BASE=GENERATED_CODE

from Demi Magus answer in /etc/apache2/envvars, cause /etc/profile seems to be ignored.

Source: https://www.phusionpassenger.com/library/indepth/environment_variables.html#apache


I'm going to assume that you do not have your secrets.yml checked into source control (ie. it's in the .gitignore file). Even if this isn't your situation, it's what many other people viewing this question have done because they have their code exposed on Github and don't want their secret key floating around.

If it's not in source control, Heroku doesn't know about it. So Rails is looking for Rails.application.secrets.secret_key_base and it hasn't been set because Rails sets it by checking the secrets.yml file which doesn't exist. The simple workaround is to go into your config/environments/production.rb file and add the following line:

Rails.application.configure do
    ...
    config.secret_key_base = ENV["SECRET_KEY_BASE"]
    ...
end

This tells your application to set the secret key using the environment variable instead of looking for it in secrets.yml. It would have saved me a lot of time to know this up front.


I had the same problem after I used the .gitignore file from https://github.com/github/gitignore/blob/master/Rails.gitignore

Everything worked out fine after I commented the following lines in the .gitignore file.

config/initializers/secret_token.rb
config/secrets.yml

this is works good https://gist.github.com/pablosalgadom/4d75f30517edc6230a67 for root user should edit

$ /etc/profile

but if you non root should put the generate code in the following

$ ~/.bash_profile

$ ~/.bash_login

$ ~/.profile

In my case, the problem was that config/master.key was not in version control, and I had created the project on a different computer.

The default .gitignore that Rails creates excludes this file. Since it's impossible to deploy without having this file, it needs to be in version control, in order to be able to deploy from any team member's computer.

Solution: remove the config/master.key line from .gitignore, commit the file from the computer where the project was created, and now you can git pull on the other computer and deploy from it.

People are saying not to commit some of these files to version control, without offering an alternative solution. As long as you're not working on an open source project, I see no reason not to commit everything that's required to run the project, including credentials.


Add config/secrets.yml to version control and deploy again. You might need to remove a line from .gitignore so that you can commit the file.

I had this exact same issue and it just turned out that the boilerplate .gitignore Github created for my Rails application included config/secrets.yml.


I've created config/initializers/secret_key.rb file and I wrote only following line of code:

Rails.application.config.secret_key_base = ENV["SECRET_KEY_BASE"]

But I think that solution posted by @Erik Trautman is more elegant ;)

Edit: Oh, and finally I found this advice on Heroku: https://devcenter.heroku.com/changelog-items/426 :)

Enjoy!


While you can use initializers like the other answers, the conventional Rails 4.1+ way is to use the config/secrets.yml. The reason for the Rails team to introduce this is beyond the scope of this answer but the TL;DR is that secret_token.rb conflates configuration and code as well as being a security risk since the token is checked into source control history and the only system that needs to know the production secret token is the production infrastructure.

You should add this file to .gitignore much like you wouldn't add config/database.yml to source control either.

Referencing Heroku's own code for setting up config/database.yml from DATABASE_URL in their Buildpack for Ruby, I ended up forking their repo and modified it to create config/secrets.yml from SECRETS_KEY_BASE environment variable.

Since this feature was introduced in Rails 4.1, I felt it was appropriate to edit ./lib/language_pack/rails41.rb and add this functionality.

The following is the snippet from the modified buildpack I created at my company:

class LanguagePack::Rails41 < LanguagePack::Rails4

  # ...

  def compile
    instrument "rails41.compile" do
      super
      allow_git do
        create_secrets_yml
      end
    end
  end

  # ...

  # writes ERB based secrets.yml for Rails 4.1+
  def create_secrets_yml
    instrument 'ruby.create_secrets_yml' do
      log("create_secrets_yml") do
        return unless File.directory?("config")
        topic("Writing config/secrets.yml to read from SECRET_KEY_BASE")
        File.open("config/secrets.yml", "w") do |file|
          file.puts <<-SECRETS_YML
<%
raise "No RACK_ENV or RAILS_ENV found" unless ENV["RAILS_ENV"] || ENV["RACK_ENV"]
%>

<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
          SECRETS_YML
        end
      end
    end
  end

  # ...

end

You can of course extend this code to add other secrets (e.g. third party API keys, etc.) to be read off of your environment variable:

...
<%= ENV["RAILS_ENV"] || ENV["RACK_ENV"] %>:
  secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
  third_party_api_key: <%= ENV["THIRD_PARTY_API"] %>

This way, you can access this secret in a very standard way:

Rails.application.secrets.third_party_api_key

Before redeploying your app, be sure to set your environment variable first: Setting SECRET_KEY_BASE in Heroku Dashboard

Then add your modified buildpack (or you're more than welcome to link to mine) to your Heroku app (see Heroku's documentation) and redeploy your app.

The buildpack will automatically create your config/secrets.yml from your environment variable as part of the dyno build process every time you git push to Heroku.

EDIT: Heroku's own documentation suggests creating config/secrets.yml to read from the environment variable but this implies you should check this file into source control. In my case, this doesn't work well since I have hardcoded secrets for development and testing environments that I'd rather not check in.


What I did : On my production server, I create a config file (confthin.yml) for Thin (I'm using it) and add the following information :

environment: production
user: www-data
group: www-data
SECRET_KEY_BASE: mysecretkeyproduction

I then launch the app with

thin start -C /whereeveristhefieonprod/configthin.yml

Work like a charm and then no need to have the secret key on version control

Hope it could help, but I'm sure the same thing could be done with Unicorn and others.


This worked for me.

SSH into your production server and cd into your current directory, run bundle exec rake secret or rake secret, you will get a long string as an output, copy that string.

Now run sudo nano /etc/environment.

Paste at the bottom of the file

export SECRET_KEY_BASE=rake secret
ruby -e 'p ENV["SECRET_KEY_BASE"]'

Where rake secret is the string you just copied, paste that copied string in place of rake secret.

Restart the server and test by running echo $SECRET_KEY_BASE.


Examples related to ruby-on-rails

Embed ruby within URL : Middleman Blog Titlecase all entries into a form_for text field Where do I put a single filter that filters methods in two controllers in Rails Empty brackets '[]' appearing when using .where How to integrate Dart into a Rails app Rails 2.3.4 Persisting Model on Validation Failure How to fix "Your Ruby version is 2.3.0, but your Gemfile specified 2.2.5" while server starting Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432? Rails: Can't verify CSRF token authenticity when making a POST request Uncaught ReferenceError: React is not defined

Examples related to ruby

Uninitialized Constant MessagesController Embed ruby within URL : Middleman Blog Titlecase all entries into a form_for text field Ruby - ignore "exit" in code Empty brackets '[]' appearing when using .where find_spec_for_exe': can't find gem bundler (>= 0.a) (Gem::GemNotFoundException) How to update Ruby Version 2.0.0 to the latest version in Mac OSX Yosemite? How to fix "Your Ruby version is 2.3.0, but your Gemfile specified 2.2.5" while server starting Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432? How to update Ruby with Homebrew?

Examples related to heroku

How to fix error "ERROR: Command errored out with exit status 1: python." when trying to install django-heroku using pip Can't push to the heroku ImproperlyConfigured: You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings How to enable CORS in flask Error: Cannot pull with rebase: You have unstaged changes How to solve error "Missing `secret_key_base` for 'production' environment" (Rails 4.1) Failed to execute 'postMessage' on 'DOMWindow': The target origin provided does not match the recipient window's origin ('null') 'heroku' does not appear to be a git repository Heroku 'Permission denied (publickey) fatal: Could not read from remote repository' woes How do I set up DNS for an apex domain (no www) pointing to a Heroku app?

Examples related to ruby-on-rails-4

Uninitialized Constant MessagesController Is the server running on host "localhost" (::1) and accepting TCP/IP connections on port 5432? NameError: uninitialized constant (rails) How to solve error "Missing `secret_key_base` for 'production' environment" (Rails 4.1) ActionController::UnknownFormat Add a reference column migration in Rails 4 PG::ConnectionBad - could not connect to server: Connection refused Auto-loading lib files in Rails 4 cannot load such file -- bundler/setup (LoadError) Rails 4: how to use $(document).ready() with turbo-links