fix: ignore unknown fields in CLUSTER SHARDS response#3843
Conversation
The CLUSTER SHARDS 'nodes' field contains a list of all nodes within the shard. Each individual node is a map of attributes that describe the node. Some attributes are optional and more attributes may be added in the future. Previously, the parser returned an error on any unrecognized field, causing breakage whenever the server introduces new attributes. Now unknown fields at both the shard level and node level are silently discarded, matching the forward-compatible behavior already used elsewhere in this codebase. Signed-off-by: Madelyn Olson <[email protected]>
|
Hi, I’m Jit, a friendly security platform designed to help developers build secure applications from day zero with an MVS (Minimal viable security) mindset. In case there are security findings, they will be communicated to you as a comment inside the PR. Hope you’ll enjoy using Jit. Questions? Comments? Want to learn more? Get in touch with us. |
|
Hello @madolson and thank you for this contribution. It makes sense to be forward compatible and ignore the unknown fields. Were there any specific ones that triggered this error for you? If so, does it make more sense to include them in the struct now? Also, since we had a similar case for Line 3186 in 65d6abd |
|
@ndyakov We hit while upgrade to Valkey 9.1. I understand that isn't Redis, but the documentation looks like they should be compatible for this dimensions, so better to make sure it doesn't break in the future!
That makes sense to me! I'm just trying to scope down the change, but happy to make more. |
There was a problem hiding this comment.
This looks good as it is.
@madolson no need to extend it at this time, there are other similar commands that try to parse the whole response and fail on unknown fields, which is not ideal. I am willing to include this change and take care of the rest when I decide on a proper approach. Thank you!
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [github.com/redis/go-redis/v9](https://github.com/redis/go-redis) | `v9.20.0` → `v9.20.1` |  |  | --- ### Release Notes <details> <summary>redis/go-redis (github.com/redis/go-redis/v9)</summary> ### [`v9.20.1`](https://github.com/redis/go-redis/releases/tag/v9.20.1): 9.20.1 [Compare Source](redis/go-redis@v9.20.0...v9.20.1) This is a patch release containing bug fixes only. There are no new features or breaking changes; upgrading from 9.20.0 is a drop-in replacement. #### 🚀 Highlights ##### RESP3 pub/sub message loss fixed `PeekPushNotificationName` previously inspected only the bytes already buffered by `bufio`, so when a push frame header straddled a buffer fill boundary it could return a **truncated** notification name (e.g. `"messa"` instead of `"message"`). The push processor then mis-routed the frame and `ReadReply` silently dropped it, causing intermittent RESP3 pub/sub message loss. The peek now grows its window (36 bytes → up to 4 KiB) and reads more from the connection until the header is complete, cleanly separating incomplete prefixes from corrupt frames (including overflow-safe bulk-length handling). Fixes [#​3839](redis/go-redis#3839). ([#​3842](redis/go-redis#3842)) by [@​ndyakov](https://github.com/ndyakov) #### 🐛 Bug Fixes - **RESP3 push peeking**: `PeekPushNotificationName` no longer returns a truncated notification name when a push frame header spans a buffer boundary, preventing silent RESP3 pub/sub message loss (fixes [#​3839](redis/go-redis#3839)) ([#​3842](redis/go-redis#3842)) by [@​ndyakov](https://github.com/ndyakov) - **`FT.HYBRID` vector params**: Vector data is now always sent via `PARAMS` with auto-generated param names (`__vector_param_N`, with collision avoidance) when `VectorParamName` is omitted, since Redis no longer accepts inline vector blobs; the `FTHybridOptions.Params` map is no longer mutated, so the same options struct can be reused across calls ([#​3844](redis/go-redis#3844)) by [@​ndyakov](https://github.com/ndyakov) - **`CLUSTER SHARDS` forward compatibility**: Unknown shard- and node-level attributes in the `CLUSTER SHARDS` reply are now skipped via `DiscardNext()` instead of erroring, so clients keep working when the server introduces new fields ([#​3843](redis/go-redis#3843)) by [@​madolson](https://github.com/madolson) - **PubSub double reconnect**: `PubSub.releaseConn` no longer reconnects twice when a connection is both unusable (or pending handoff) and reports a bad-connection error, avoiding a wasted connection establish-then-close cycle ([#​3833](redis/go-redis#3833)) by [@​cxljs](https://github.com/cxljs) #### 👥 Contributors We'd like to thank all the contributors who worked on this release! [@​cxljs](https://github.com/cxljs), [@​madolson](https://github.com/madolson), [@​ndyakov](https://github.com/ndyakov) *** **Full Changelog**: <redis/go-redis@v9.20.0...v9.20.1> </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - Between 12:00 AM and 03:59 AM (`* 0-3 * * *`) - Automerge - Between 12:00 AM and 03:59 AM (`* 0-3 * * *`) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMTQuNSIsInVwZGF0ZWRJblZlciI6IjQzLjIxNC41IiwidGFyZ2V0QnJhbmNoIjoiZm9yZ2VqbyIsImxhYmVscyI6WyJkZXBlbmRlbmN5LXVwZ3JhZGUiLCJ0ZXN0L25vdC1uZWVkZWQiXX0=--> Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/13061 Reviewed-by: Mathieu Fenniak <[email protected]>
Summary
The
CLUSTER SHARDSresponse parser errors on any unrecognized field, breaking clients whenever the server introduces new node or shard attributes.The
nodesfield contains a list of all nodes within the shard. Each individual node is a map of attributes that describe the node. Some attributes are optional and more attributes may be added in the future. The current list of attributes:The parser should be forward-compatible. Unknown fields are now discarded via
rd.DiscardNext(), the same pattern used elsewhere in this codebase (e.g.,FunctionListCmd,ModuleLoadexConfigparsing).Changes:
fmt.Errorfon unknown node-level fields withrd.DiscardNext()fmt.Errorfon unknown shard-level fields withrd.DiscardNext()Test plan
Note
Medium Risk
Changes cluster topology parsing used for routing; incorrect discard logic could break cluster clients, but behavior aligns with existing DiscardNext patterns and is covered by new unit tests.
Overview
The
CLUSTER SHARDSreply parser no longer fails when Redis returns unknown shard- or node-level attributes. Unrecognized keys are skipped withrd.DiscardNext()instead of returningfmt.Errorf, matching forward-compatibility used elsewhere (e.g.XInfo*parsers).Tests assert that known
slots/nodesdata still parses when extra fields are present (string, integer, and array-valued unknown node fields).Reviewed by Cursor Bugbot for commit 7f4fdaf. Bugbot is set up for automated code reviews on this repo. Configure here.