116

ActionDispatch::Cookies::CookieOverflow in UsersController#create

I have this error when I try to open the page. I do not know how to debug this error. Do you have any suggestion for this problem?

def create
  @user = User.new(params[:user])
  sign_in @user

  if @user.save
    @user.folders.create(:folder_name=>"Default Folder", :user_id=>@user.id)
    flash[:success] = "Welcome to Bunch<it>! "
    redirect_to @user
  else
    @title = "Sign up"
    render 'new'
  end
end


def sign_in(user)
  cookies.permanent.signed[:remember_token] = [user.id, user.salt]
  session[:current_user] = user
  current_user = user
end
Gagan Gami
  • 10,121
  • 1
  • 29
  • 55
erogol
  • 13,156
  • 33
  • 101
  • 155
  • 1
    this error comes when you have a large data/object in session. Can you share the code for create action in controller? – Naren Sisodiya Feb 27 '12 at 23:12
  • 1
    Duplicate of http://stackoverflow.com/questions/4782611/rails-how-to-save-a-big-array-in-session-actiondispatchcookiescookieoverf ? – iblue Feb 27 '12 at 23:27
  • 3
    While the answers about changing your session store are correct, i'd question why you want to store the entire user in the session. If you have to store something, store the user_id (although that's already in your cookie) – Frederick Cheung Feb 28 '12 at 17:50
  • Simply go to the browser cache store, and clear cookies belonging to that specific website url. for me it happens mostly in localhost. – ben Mar 30 '15 at 12:51
  • I had created a user model with `Devise` and I hadn't restarted my development server after running the migrations. Once I did, the error stopped. – wuliwong Aug 28 '17 at 22:50

8 Answers8

168

You've got a 4kb limit on what you can store in a cookie, and when Rails converts your object into text for writing to the cookie its probably bigger than that limit.

Ruby on Rails ActionDispatch::Cookies::CookieOverflow error

That way this CookieOverflow Error occurs.

The easiest way to solve this one is, you need change your session_store and don't use the cookie_store. You can use the active_record_store by example.

Here is the steps

  1. Generate a migration that creates the session table

    rake db:sessions:create
    
  2. Run the migration

    rake db:migrate
    
  3. Modify config/initializers/session_store.rb from

    (App)::Application.config.session_store :cookie_store, :key => 'xxx'
    

    to

    (App)::Application.config.session_store :active_record_store
    

Once you’ve done the three steps, restart your application. Rails will now use the sessions table to store session data, and you won’t have the 4kb limit.

colllin
  • 9,442
  • 9
  • 49
  • 65
AMIC MING
  • 6,306
  • 6
  • 46
  • 62
83

To make the :active_record_store functionality works in Rails 4/5, you must add the activerecord-session_store gem to your Gemfile:

gem 'activerecord-session_store'

then run the migration generator:

rails generate active_record:session_migration
rake db:migrate

And finally set your session store in config/initializers/session_store.rb:

Rails.application.config.session_store :active_record_store, :key => '_my_app_session'

UPDATE:

If anyone is receiving a null value in column "session_id" violates not-null constraint message in rails 4, there's a workaround in github(not tested). You must to create an initializer with ActiveRecord::SessionStore::Session.attr_accessible :data, :session_id

Alter Lagos
  • 12,090
  • 1
  • 70
  • 92
  • Did you not get an error when using this gem? I get the following : `ERROR: null value in column "session_id" violates not-null constraint` – Peter Sep 06 '13 at 09:08
  • @Peter It didn't happened me, but [here](https://github.com/rails/activerecord-session_store/issues/6) still appears as an open issue. My only advise is write a comment in that issue to watch it until someone put a fix. Sorry :/ – Alter Lagos Sep 06 '13 at 14:26
  • @Peter I'm not sure if is too late, but anyway check my updated answer – Alter Lagos Nov 13 '13 at 16:00
  • 2
    After running "rails generate active_record:session_migration" don't forget to run: "rake db:migrate"! – Patrice Gagnon May 21 '14 at 15:33
  • 2
    what if I don't want to store anything in the DB how I can rescue the error? I tried rescue_from ActionDispatch::Cookies::CookieOverflow, :with => :render_404 in the ApplicationController but it didn't work – nisevi Jul 17 '15 at 22:04
30

If you're seeing this, check that you're not blowing up some session data. In my case, it was thousands of the same message pumped into the flash message. Just saying.

I'll add that if you think the solution is to make your cookie store bigger (as most of the other answers suggest), you're probably better off rethinking what you're actually putting in cookies. If you need more than a couple of auth tokens, session ID's, and maybe a few layout/tracking cookies, you're living in the 90's.

David Hempy
  • 5,373
  • 2
  • 40
  • 68
  • 1
    I was deep merging some params to save state! – Anwar Sep 17 '17 at 18:36
  • 3
    This was the cause of the error for me as well. Putting too much data into the flash message. – knubie Nov 01 '17 at 18:18
  • 1
    Yes, I had this issue when implementing OmniAuth-Keycloak strategy. Keycloak provides lots of information, including user's accesses list. Only a few is relevant for storing as a cookie ... – user1185081 Dec 15 '21 at 10:47
  • 1
    Gold! It was a flash message issue. – João Paulo Motta Mar 23 '22 at 14:34
  • @user1185081, I am also implementing OmniAuth-Keycloak and I need to store access_token, refresh_token, id_token into session as those will be required to get the new access token and also to logout the user. How did you mange this? – Sanjay Prajapati May 24 '23 at 04:38
10

It's not a good idea to store a model object in the session.

Check out this railscast on this topic: http://railscasts.com/episodes/13-dangers-of-model-in-session?autoplay=true

It's a better practice to store the id (user's id in this case) inside the session. Then you won't have this problem.

(See Frederick Cheung comment above also).

Zack Xu
  • 11,505
  • 9
  • 70
  • 78
9

the error message clearly indicates the problem with cookie store size that's overflow.

Your sessions (by default in cookie) needs to be moved to Active record store or memcache store to fix this issue.

For Databased sessions:

config.action_controller.session_store = :active_record_store

You need to create the session table as below

rake db:sessions:create
rake db:migrate

OR

For Memcache sessions:

config.action_controller.session_store = :mem_cache_store

Also you need to setup a mem cache server and configure it as below:

config.cache_store = :mem_cache_store, 'localhost', '127.0.0.1:11211',
{:namespace => 'myapp123'}
sjain
  • 23,126
  • 28
  • 107
  • 185
9

That error is because you are trying to serialize the user model When storing an object in a cookie, rails will use Marshal.dump which can produce a large amount of content since it's everything on the user record

Instead of storing the actual user record with session[:current_user] = user try just storing the users' ID then have a method a method to look up the user from that e.g.

def sign_in(user)
  ...
  session[:current_user_id] = user.id
end

def current_user
  @current_user ||= User.find(session[:current_user_id])
end
cianmce
  • 454
  • 5
  • 4
4

my problem was because of code

rescue StandardError => e
  flash[:error] = "Error was #{error.message}"
end

the error.message was too big

srghma
  • 4,770
  • 2
  • 38
  • 54
  • That is correct, maximum size of the cookie is 4kb; then the flash is stored in the session it seems, then it overflows with that :error assigning – damuz91 Jun 10 '22 at 16:07
1

This error appeared for me when I was running a specs. After updating Capybara from 1.x to 2.x. Just rake tmp:clear solved it.

Artur79
  • 12,705
  • 1
  • 22
  • 22