Skip to content

MOD-15749 Short-form CLUSTERSET: reject when the cluster API has no usable node endpoints - #101

Closed
gabsow wants to merge 1 commit into
masterfrom
tom.gabsow/MOD-15749-short-form-validate-node-endpoints
Closed

MOD-15749 Short-form CLUSTERSET: reject when the cluster API has no usable node endpoints#101
gabsow wants to merge 1 commit into
masterfrom
tom.gabsow/MOD-15749-short-form-validate-node-endpoints

Conversation

@gabsow

@gabsow gabsow commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Problem

The short form of CLUSTERSET derives each shard's ip:port from RedisModule_GetClusterNodeInfo. On Redis builds where the module cluster topology isn't fully populated — notably Redis Enterprise without the node-port backport, where getNodeDefaultClientPort() returns 0 (RED-202230) — that API yields no usable endpoint (port 0 / empty ip), and today's code:

  • doesn't validate the port/ip (only checks rc != REDISMODULE_OK), so it builds nodes pointing at port 0 — or skips all nodes and builds an empty topology;
  • still return REDISMODULE_OK, so the caller (DMC) gets +OK, believes the cluster is configured, and never falls back to the long form → cross-shard commands silently break;
  • RedisModule_Assert(slots != NULL) can crash the shard outright.

RediSearch hit exactly this in RE and fails loudly (returns an "invalid topology" error). LibMR currently fails silently — worse.

Fix

Mirror RediSearch's defensive handling in SetClusterDataShortForm:

  1. Skip nodes with no usable endpoint (rc != OK || port <= 0 || ip[0] == '\0'); zero-init the locals so the check is reliable.
  2. Replace RedisModule_Assert(slots != NULL) with a soft skip (no field crash).
  3. If no valid master shards remain, MR_ClusterFree() and return an error so the caller can fall back to the long-form CLUSTERSET (which carries endpoints explicitly).

This does not make the short form work in RE (that needs the core fix, RED-202230). It makes the module fail safely there — return an error instead of silently installing a broken topology — which is a prerequisite for DMC's try-then-fallback.

Testing

cluster.c compiles and libmr.a links clean. The new paths require the RE port bug to exercise (no OSS redis returns port 0), so they're covered by code review here + the enterprise beta; the existing testShortFormClusterSetWithoutSlotRangesApi (no-API path) and the RedisTimeSeries oss-cluster flow test (success path) are unaffected.

🤖 Generated with Claude Code


Note

Medium Risk
Changes cluster topology installation for a critical cross-shard path; behavior is more defensive but alters success/failure when the cluster API is incomplete (e.g. enterprise without port backport).

Overview
Short-form CLUSTERSET in SetClusterDataShortForm no longer treats a partially empty Redis module cluster API as success.

Nodes are skipped when RedisModule_GetClusterNodeInfo fails or returns an empty IP or non-positive port (e.g. Redis Enterprise without the node-port backport, RED-202230). RedisModule_Assert(slots != NULL) is replaced with a warning and skip when slot ranges are missing.

If no valid master shards remain after that pass, the half-built topology is torn down via MR_ClusterFree() and the function returns REDISMODULE_ERR so callers like DMC can fall back to long-form CLUSTERSET instead of replying OK with port-0 or empty topology.

Reviewed by Cursor Bugbot for commit 594375d. Bugbot is set up for automated code reviews on this repo. Configure here.

…sable node endpoints

The short form derives each shard's ip:port from RedisModule_GetClusterNodeInfo.
On Redis builds where the module cluster topology is not fully populated -- e.g.
Redis Enterprise without the node-port backport, where getNodeDefaultClientPort()
returns 0 (RED-202230) -- that API yields no valid endpoint, so we would build an
empty/port-0 topology and still reply +OK. The caller (DMC) then believes the
cluster is configured and never falls back to the long form, leaving cross-shard
commands silently broken (and risking an assert crash on the slot-ranges path).

Mirror RediSearch's defensive handling:
- skip nodes whose endpoint is missing (rc != OK, port <= 0, or empty ip);
- replace RedisModule_Assert(slots != NULL) with a soft skip (no field crash);
- if no valid master shards remain, reply with an error so the caller can fall
  back to the long-form CLUSTERSET (which carries the endpoints explicitly).

This does not make the short form work in RE (that needs the core fix RED-202230);
it makes TimeSeries fail safely there instead of silently misconfiguring.
@gabsow

gabsow commented Jul 5, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #103, which combines this with the sibling short-form CLUSTERSET fail-safe into a single PR (one review + one pin bump). Closing in favour of #103.

@gabsow gabsow closed this Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant