rails: Error loading cached data after upgrade to 7.1 `dump format error`

We have a Rails 7.0.5.1 app set with config.load_defaults 6.0

When attempting to upgrade to 7.1.0-alpha, with cached data already present in the app (Redis cache) I’m getting an error when Rails attempts to read the data with Marshal.load in Marshal61WithFallback (here).

Argument Error 
dump format error (user class)

The cached data is correctly identified as 6.1 with Marshal61WithFallback::MARSHAL_SIGNATURE but fails to load.

I’ve created an example app where you can easily replicate this, (see reproduction instructions below).

From reading recent commits and the CHANGELOG, I can see that @jonathanhefner did make some --recent changes in here, but from what I can see, this should just work, without any necessary cache migration.

Steps to reproduce

git clone https://github.com/matthutchinson/rails-caching-example
cd rails-caching-example
bin/setup
rails db:seed
rails dev:cache
rails server
open https://localhost:3000

# visit page, causing partials to be cached
# stop server
# edit Gemfile, set to use edge rails from gh master

bundle update rails
rails server
open https://localhost:3000
# page errors when loading cached data with dump format error (user class)

Here’s a what the dumped var looks like in my example app and I’m caching partials in high_scores#index with;

<%= render partial: "high_score", collection: @high_scores, cached: true %>

"\u0004\bo: ActiveSupport::Cache::Entry\t:\v@valueIC:\u001DActionView::OutputBuffer\"\u0001\xAB<div id=\"high_score_1\">\n  <p>\n    <strong>Game:</strong>\n    <a href=\"/high_scores/1\">Tetris</a>\n  </p>\n\n  <p>\n    <strong>Score:</strong>\n    100000\n  </p>\n\n</div>\n<hr/>\n\a:\u0006ET:\u000F@html_safeT:\r@versionI\"\u001920230628145327125454\u0006;\bT:\u0010@created_atf\u00060:\u0010@expires_in0"

Expected behavior

Cached partial data should be loaded and displayed without error

Actual behavior

Error raised when loading cached data from Marshal.load

Argument Error 
dump format error (user class)
Screenshot 2023-06-28 at 16 35 43

System configuration

Rails version: 7.1.0-alpha (migrating from 7.0.5.1) Ruby version: 3.1.2 and 3.2.0

Other Notes:

  • I thought this commit might have been the cause, but reverting to the commit before that, I get the same issue.
  • Clearing the cache will fix the issue, but in production, we’d really prefer not to have to do that.
  • If clearing the cache is a requirement, we should update the docs and upgrade guide to explain that.

cc @jonathanhefner

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 19 (17 by maintainers)

Commits related to this issue

Most upvoted comments

@sedubois the fix is in 7-1-stable now.

This may be due to our use of a custom cache store

Yeah, your custom cache store will have to convert the Marshal error into an ActiveSupport::Cache::DeserializationError: https://github.com/rails/rails/pull/48663/files#diff-0dbd64061e6262143eb934c41727278edb775d89d42165c79519a3bf3a1d1321R62-R66

Part two is here: https://github.com/rails/rails/pull/48663

I’ll merge tomorrow if no-one objects. Once this is merged this should allow you to upgrade seamlessly, however you will see some increase in cache misses when you first roll out.

I just opened part 1 of the fix: https://github.com/rails/rails/pull/48645

The next step is to rescue cache deserialization issues, and treat them as cache misses.

@matthutchinson thanks. I’ll try to find a solution today.

Right now I’m thinking we could do two birds one stone, by caching these fragments as bare strings:

But either way, that requires to bust these caches, which we can probably do by changing the prefix in https://github.com/rails/rails/blob/c388a4dcf580281aef4e341f87c52956b0b0057a/actionpack/lib/abstract_controller/caching/fragments.rb