Repository navigation
Redis tag-index pipeline fallback removes indices for live cache entries #41529
Description
Preconditions and environment
magento/magento22.4-developat commit4962c46d932c2b69989f4fafbe0157739ba781a7.- PHP 8.5.9, Redis 8.10.0, Predis 3.7.0 (satisfies the upstream
^3.5requirement), Symfony Cache 7.4.17. - Isolated PHPUnit test of the upstream
RedisTagAdaptersource with a realRedisAdapterand disposable Redis instance. This was not a full Magento storefront test. - The Redis ACL user was created with
ACL SETUSER repro on nopass ~* +@all -eval -evalsha -script. Authenticating asrepromakespruneTagIndex()take its documented pipeline fallback. The same Redis instance permits scripts for the control run.
Steps to reproduce
- Save a cache item with ID
entryand valueold, then callRedisTagAdapter::onSave('entry', ['TAG']). ConfirmgetIdsMatchingAnyTags(['TAG'])containsentry. - Begin
deleteByIds(['entry']). In thedeleteItems()call, delete the old cache value, then use a second Redis client to save a new value under the same ID and callonSave('entry', ['TAG'])before the originaldeleteItems()returnstrue. This controls the concurrent re-save interleaving without relying on timing. - Let
deleteByIds()complete and read both the cache item and tag index.
There is a second failure path: make deleteItems() return false while leaving the original item in place, then call deleteByIds(['entry']) and read the item and tag index.
Expected result
Whenever entry still has a stored cache value, it remains in the TAG set, its reverse index, and cache:all_ids. getIdsMatchingAnyTags(['TAG']) should return entry.
Actual result
In both paths, the cache value remains readable, but getIdsMatchingAnyTags(['TAG']) returns an empty array. Direct checks show that membership in the tag set, reverse index, and cache:all_ids is 0 in each case. Later tag-based invalidation can miss this live entry.
The two PHPUnit cases fail on the index snapshot with the script-denied ACL user (2 tests, 18 assertions, 2 failures). They both pass against the same Redis instance when scripts are allowed (2 tests, 18 assertions).
Additional information
deleteByIds() calls pruneTagIndex() even if deletion fails. The pipeline fallback removes index entries without checking whether the data key still exists. The atomic script has a data-existence guard.
This is distinct from #41004, where reverse-index keys remained after the cache data was deleted. Here the cache data remains but its index is removed. I have not reproduced this against Redis Cluster or a full installed Magento storefront.
Release note
No response
Triage and priority
- Severity: S0 - Affects critical data or functionality and leaves users without workaround.
- Severity: S1 - Affects critical data or functionality and forces users to employ a workaround.
- Severity: S2 - Affects non-critical data or functionality and forces users to employ a workaround.
- Severity: S3 - Affects non-critical data or functionality and does not force users to employ a workaround.
- Severity: S4 - Affects aesthetics, professional look and feel, “quality” or “usability”.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsReady for Confirmation
Activity
m2-assistant commentedon Oct 12, 2026
Hi @mattmacrocket. Thank you for your report.
To speed up processing of this issue, make sure that the issue is reproducible on the vanilla Magento instance following Steps to reproduce.
@magento I am working on thisJoin Magento Community Engineering Slack and ask your questions in #github channel.
⚠️ According to the Magento Contribution requirements, all issues must go through the Community Contributions Triage process. Community Contributions Triage is a public meeting.
🕙 You can find the schedule on the Magento Community Calendar page.
📞 The triage of issues happens in the queue order. If you want to speed up the delivery of your contribution, join the Community Contributions Triage session to discuss the appropriate ticket.
github-jira-sync-bot commentedon Oct 12, 2026
✅ Jira issue https://jira.corp.adobe.com/browse/AC-19243 is successfully created for this GitHub issue.
bluefairydevelopment commentedon Oct 27, 2026
Reproduced on 2.4-develop with Redis 7.0.15 and an ACL user that may not run scripts. After a prune of an id whose value still exists, the value is readable but the tag lookup no longer finds it. With scripts allowed, it does. Fix and tests are in #41719: the pipelined fallback now checks that the data key is gone before pruning, like the Lua script.