fix(storage): add no-store cache control to download
fix(storage): add no-store cache control to download
Description:
This Pull Request addresses an issue where the storage.download() method would frequently return stale or cached data instead of the most recent version of a file. By explicitly adding the Cache-Control: no-store header to the download request, we ensure that the client always fetches the latest file content directly from the server, bypassing any intermediate caches.
What changed?
I modified the StorageFileApi.ts file within the storage-js package. Specifically, I updated the download
method to include the Cache-Control header with a value of no-store in the options object passed to the underlying
get request function.
Why was this change needed?
This change was necessary to resolve Issue #41841. Users reported that after updating a file in Supabase Storage, immediate subsequent calls to _download()_ would return the old file content. This behavior suggests that browsers or CDNs were serving a cached response. Adding no-store is a standard HTTP mechanism to instruct all caching layers to avoid storing the response, thereby guaranteeing that the application receives the most up-to-date data.
Breaking changes This Pull Request contains no breaking changes. It only modifies internal header logic for the download request and does not alter the public API signature or return types.
related
- https://github.com/supabase/supabase/issues/41841
- https://github.com/supabase/supabase/pull/41855
Thanks for the PR @Akkii88 . I am not sure I will approve, need to discuss/think about it. In the meantime, can you please remove pnpm lock file from git? We use npm!
Thank you again very much for contributing to Supabase! You're helping us make the tool better! π
coverage: 80.997%. remained the same when pulling 7d09eea0a504636f62c5a4861eb85ad6d93c66d2 on Akkii88:Issue-Fix into 09aa10628b00cbdf65ace0f9e8e79237e7c0c1dc on supabase:master.
π Walkthrough
Walkthrough
The StorageFileApi.download method now merges a Cache-Control: no-store header with existing headers in its fetch request, preventing caching of downloaded files instead of sending only base headers.
Changes
| Cohort / File(s) | Summary |
|---|---|
StorageFileApi Header Configuration packages/core/storage-js/src/packages/StorageFileApi.ts |
Updated download method to merge Cache-Control: no-store header with existing request headers, explicitly disabling caching for file downloads. |
Estimated code review effort
π― 1 (Trivial) | β±οΈ ~3 minutes
π₯ Pre-merge checks | β 3
β Passed checks (3 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | β Passed | Check skipped - CodeRabbitβs high-level summary is enabled. |
| Title check | β Passed | The title 'fix(storage): add no-store cache control to download' accurately describes the main change: adding a Cache-Control header to the download method in StorageFileApi. |
| Docstring Coverage | β Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
βοΈ Tip: You can configure your own custom pre-merge checks in the settings.
β¨ Finishing touches
- [ ] π Generate docstrings
π§ͺ Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
Hi @Akkii88!
Thank you for identifying this issue and proposing a fix. The problem you've identified is real, download() doesn't provide a way to control caching, which causes stale data issues in Edge Functions.
However, we can't merge this PR as-is because hardcoding Cache-Control: no-store would:
- Force all users to bypass caching - including browsers and Node.js environments where caching improves performance
- No opt-out mechanism - removes user control over caching behavior
- Performance impact - increases server load, bandwidth costs, and latency for all users
- Breaking change - alters default behavior that existing applications may rely on
Better Approach
I've opened a new PR that takes a different approach: exposing fetch parameters rather than hardcoding headers.
This allows Edge Function users to opt-in when needed:
// Edge Functions - bypass cache
const { data } = await supabase.storage
.from('avatars')
.download('file.png', {}, { cache: 'no-store' })
// Default behavior (unchanged)
const { data } = await supabase.storage
.from('avatars')
.download('file.png')
Thank you SO much for contributing to Supabase! Your PR actually helped me identify a problem and come up with a solution. Please do not be discouraged to contribute again in the future. Contributions like yours are what makes Supabase better! π