dromara/Sa-Token · critical · SaTokenException

Alone-Redis 哨兵模式需要配置 sentinel.nodes

Error message

Alone-Redis 哨兵模式需要配置 sentinel.nodes

What it means

SaTokenException thrown by SaAloneRedisInject (spring-boot4 variant) when sa-token.alone-redis.pattern=sentinel is configured but sentinel.nodes is missing. Building a RedisSentinelConfiguration requires the sentinel node addresses; the master name and sentinel password are read afterwards but the node list is the hard prerequisite.

Source

Thrown at sa-token-plugin/sa-token-alone-redis-by-spring-boot4/src/main/java/cn/dev33/satoken/dao/alone/SaAloneRedisInject.java:127

				List<RedisNode> serverList = cluster.getNodes().stream().map(node -> {
					String[] ipAndPort = node.split(":");
					return new RedisNode(ipAndPort[0].trim(), Integer.parseInt(ipAndPort[1]));
				}).collect(Collectors.toList());
				redisClusterConfig.setClusterNodes(serverList);
				if (cluster.getMaxRedirects() != null) {
					redisClusterConfig.setMaxRedirects(cluster.getMaxRedirects());
				}
				redisAloneConfig = redisClusterConfig;
			} else if (pattern.equals("sentinel")) {
				// 哨兵集群模式
				RedisSentinelConfiguration redisSentinelConfiguration = new RedisSentinelConfiguration();
				redisSentinelConfiguration.setDatabase(cfg.getDatabase());
				redisSentinelConfiguration.setUsername(cfg.getUsername());
				redisSentinelConfiguration.setPassword(RedisPassword.of(cfg.getPassword()));

				DataRedisProperties.Sentinel sentinel = cfg.getSentinel();
				if (sentinel == null || sentinel.getNodes() == null) {
					throw new SaTokenException("Alone-Redis 哨兵模式需要配置 sentinel.nodes");
				}
				redisSentinelConfiguration.setMaster(sentinel.getMaster());
				redisSentinelConfiguration.setSentinelPassword(sentinel.getPassword());
				List<RedisNode> serverList = sentinel.getNodes().stream().map(node -> {
					String[] ipAndPort = node.split(":");
					return new RedisNode(ipAndPort[0].trim(), Integer.parseInt(ipAndPort[1]));
				}).collect(Collectors.toList());
				redisSentinelConfiguration.setSentinels(serverList);

				redisAloneConfig = redisSentinelConfiguration;
			} else if (pattern.equals("socket")) {
				// socket 连接单体 Redis
				RedisSocketConfiguration redisSocketConfiguration = new RedisSocketConfiguration();
				redisSocketConfiguration.setDatabase(cfg.getDatabase());
				redisSocketConfiguration.setUsername(cfg.getUsername());
				redisSocketConfiguration.setPassword(RedisPassword.of(cfg.getPassword()));
				String socket = environment.getProperty(ALONE_PREFIX + ".socket", "");
				redisSocketConfiguration.setSocket(socket);

View on GitHub (pinned to ac2c7f6e94)

Solutions

  1. Add sa-token.alone-redis.sentinel.nodes: ["sentinel1:26379", "sentinel2:26379"] and sentinel.master: mymaster.
  2. Fix yaml nesting so sentinel: is a child of sa-token.alone-redis.
  3. Set sentinel.password if the sentinels themselves require auth.
  4. Confirm pattern is exactly 'sentinel'.

Example fix

# before
sa-token:
  alone-redis:
    pattern: sentinel
    sentinel:
      master: mymaster

# after
sa-token:
  alone-redis:
    pattern: sentinel
    sentinel:
      master: mymaster
      password: sentinel-pass
      nodes:
        - 10.0.0.1:26379
        - 10.0.0.2:26379
        - 10.0.0.3:26379
Defensive patterns

Strategy: validation

Validate before calling

if ("sentinel".equals(props.getPattern()) && (props.getSentinel() == null || props.getSentinel().getNodes() == null)) {
    throw new IllegalStateException("alone-redis sentinel mode requires sentinel.nodes and master");
}

Prevention

When it happens

Trigger: Setting sa-token.alone-redis.pattern=sentinel without a sa-token.alone-redis.sentinel.nodes list, or with nodes nested incorrectly so DataRedisProperties.Sentinel#getNodes() returns null. The check also fires when the whole sentinel: block is omitted (sentinel == null).

Common situations: Switching the alone-redis connection to a sentinel deployment and forgetting the topology block; yaml indentation mistakes; providing only sentinel.master and assuming nodes are inferred.

Related errors


AI-assisted analysis of dromara/Sa-Token@ac2c7f6e94 (2026-08-14). Data as JSON: /api/errors/d8bb69b53995c316. Report an issue: GitHub.