---
title: "Migrating existing session cookies while upgrading"
description:
  "Safely upgrade to Rails 4.1 and migrate existing session cookies without
  forcing users to login again."
canonical_url: "https://www.bigbinary.com/blog/migrating-existing-session-cookies-while-upgrading-to-rails-4-1-and-above"
markdown_url: "https://www.bigbinary.com/blog/migrating-existing-session-cookies-while-upgrading-to-rails-4-1-and-above.md"
---

# Migrating existing session cookies while upgrading

Safely upgrade to Rails 4.1 and migrate existing session cookies without forcing
users to login again.

- Author: Prathamesh Sonpatki
- Published: December 23, 2014
- Categories: Rails

Rails 4.1 introduced [JSON](https://github.com/rails/rails/pull/13692)
[serialization](https://github.com/rails/rails/pull/13945) for cookies. Earlier
all the cookies were serialized using Marshal library of Ruby. The marshalling
of cookies can be
[unsafe](http://matt.aimonetti.net/posts/2013/11/30/sharing-rails-sessions-with-non-ruby-apps/)
because of the possibility of remote code execution vulnerability. So the change
to `:json` is welcoming.

The new applications created with Rails 4.1 or 4.2 have `:json` as the default
cookies serializer.

`rake rails:update` used for upgrading existing Rails apps to new versions
rightly changes the serializer to `:json`.

```ruby
Rails.application.config.action_dispatch.cookies_serializer = :json
```

## Deserialization error

However that change can introduce an issue in the application.

Consider a scenario where the cookies are being used for session storage. Like
many normal Rails apps, the `current_user_id` is being stored into the session.

```ruby
session[:user_id] = current_user_id
```

Before Rails 4.1 the cookie will be handled by Marshal serializer.

```ruby
cookie = Marshal.dump(current_user_id) # 42 => "\x04\bi/"
Marshal.load(cookie) # "\x04\bi/" => "42"
```

After the upgrade the application will try to unserialize cookies using `JSON`
which were serialized using `Marshal`.

```ruby
JSON.parse cookie # Earlier dumped using Marshal
# JSON::ParserError: 757: unexpected token at i/'
```

So the deserialization of the existing cookies will fail and users will start
getting errors.

## Hybrid comes to rescue

To prevent this Rails provides with a `hybrid` serializer. The `hybrid`
serializer deserializes marshalled cookies and stores them in JSON format for
the next use. All the new cookies will be serialized in the JSON format. This
gives happy path for migrating existing marshaled cookies to new Rails versions
like 4.1 and 4.2.

To use this hybrid serializer, set cookies_serializer config as `:hybrid` as
follows:

```ruby
Rails.application.config.action_dispatch.cookies_serializer = :hybrid
```

After this, all the existing marshalled cookies will be migrated to `:json`
format properly and in the future upgrade of Rails, you can safely change the
config from `:hybrid` to `:json` which is the default and safe value of this
config.

Since this blog was published Rails has changed a bit. You might run into a few
gotchas. Dylan has written about
[how to handle those gotchas here](https://dylansreile.medium.com/gotchas-with-rails-hybrid-cookie-serialization-841612ebea80).

## Links

- [Human page](https://www.bigbinary.com/blog/migrating-existing-session-cookies-while-upgrading-to-rails-4-1-and-above)
