microsoft/garnet · critical · GarnetException
Cluster announce endpoint does not match list of listen endp
Error message
Cluster announce endpoint does not match list of listen endpoints provided!
What it means
GarnetException thrown during Options.Initialize when ClusterAnnounceIp is set but the resulting announce endpoint (ClusterAnnounceIp:ClusterAnnouncePort) does not match any of the parsed listen endpoints by address and port. The match allows wildcard addresses (IPAddress.Any / IPv6Any) but requires the port to align. This prevents a node from announcing a cluster address that clients cannot actually reach on the listen socket.
Source
Thrown at libs/host/Configuration/Options.cs:779
var checkpointDir = CheckpointDir;
if (!useAzureStorage) checkpointDir = new DirectoryInfo(string.IsNullOrEmpty(checkpointDir) ? (string.IsNullOrEmpty(logDir) ? "." : logDir) : checkpointDir).FullName;
if (!Format.TryParseAddressList(Address, Port, out var endpoints, out _, ProtectedMode == CommandLineBooleanOption.True)
|| endpoints.Length == 0)
throw new GarnetException($"Invalid endpoint format {Address} {Port}.");
EndPoint[] clusterAnnounceEndpoint = null;
if (ClusterAnnounceIp != null)
{
ClusterAnnouncePort = ClusterAnnouncePort == 0 ? Port : ClusterAnnouncePort;
clusterAnnounceEndpoint = Format.TryCreateEndpoint(ClusterAnnounceIp, ClusterAnnouncePort, tryConnect: false, logger: logger);
if (clusterAnnounceEndpoint == null || !endpoints.Any(endpoint =>
endpoint is IPEndPoint listenEp && clusterAnnounceEndpoint[0] is IPEndPoint announceEp &&
listenEp.Port == announceEp.Port &&
(listenEp.Address.Equals(announceEp.Address) ||
listenEp.Address.Equals(IPAddress.Any) ||
listenEp.Address.Equals(IPAddress.IPv6Any))))
throw new GarnetException("Cluster announce endpoint does not match list of listen endpoints provided!");
}
if (!string.IsNullOrEmpty(UnixSocketPath))
endpoints = [.. endpoints, new UnixDomainSocketEndPoint(UnixSocketPath)];
// Unix file permission octal to UnixFileMode
var unixSocketPermissions = (UnixFileMode)Convert.ToInt32(UnixSocketPermission.ToString(), 8);
var revivBinRecordSizes = this.RevivBinRecordSizes?.ToArray();
var revivBinRecordCounts = this.RevivBinRecordCounts?.ToArray();
bool hasRecordSizes = revivBinRecordSizes?.Length > 0, hasRecordCounts = revivBinRecordCounts?.Length > 0;
bool useRevivBinsPowerOf2 = enableRevivification; // may be overridden
if (hasRecordSizes)
{
if (hasRecordCounts && revivBinRecordCounts.Length > 1 && revivBinRecordCounts.Length != revivBinRecordSizes.Length)
throw new Exception("Incompatible revivification record size and count cardinality.");
if (RevivInChainOnly.GetValueOrDefault())View on GitHub (pinned to 951b0fc683)
Solutions
- Ensure ClusterAnnouncePort matches the port of one of your listen endpoints (or leave it 0 to default to Port).
- Set ClusterAnnounceIp to an address that is either one of your bind addresses or matches a wildcard bind (0.0.0.0/::).
- If behind NAT, set the announce IP to the externally reachable IP and ensure the announce port matches the externally mapped port that forwards to a real listen port.
- Remove --cluster-announce-ip if clustering is not needed.
Example fix
// before: announce port does not match listen port options.Address = "0.0.0.0"; options.Port = 6379; options.ClusterAnnounceIp = "10.0.0.5"; options.ClusterAnnouncePort = 7000; // after: announce port aligns with listen port options.Address = "0.0.0.0"; options.Port = 6379; options.ClusterAnnounceIp = "10.0.0.5"; options.ClusterAnnouncePort = 6379;
Defensive patterns
Strategy: validation
Validate before calling
using System.Net;
using System.Linq;
bool AnnounceMatchesListen(string announceIp, int announcePort, EndPoint[] listenEndpoints)
{
if (string.IsNullOrEmpty(announceIp)) return true;
var announceAddr = IPAddress.Parse(announceIp);
return listenEndpoints.OfType<IPEndPoint>().Any(le =>
le.Port == announcePort &&
(le.Address.Equals(announceAddr) ||
le.Address.Equals(IPAddress.Any) ||
le.Address.Equals(IPAddress.IPv6Any)));
} Try / catch
try
{
options.Initialize(logger);
}
catch (GarnetException ex) when (ex.Message.Contains("Cluster announce endpoint"))
{
logger.LogCritical("Cluster announce {Ip}:{Port} does not match any listen endpoint.", options.ClusterAnnounceIp, options.ClusterAnnouncePort);
throw;
} Prevention
- Ensure ClusterAnnouncePort matches a real listen port (or leave it 0 to inherit Port).
- In NAT environments, verify the announce IP is externally reachable and maps to a listen port.
- Document the announce/listen relationship in the node's deployment config.
When it happens
Trigger: Setting --cluster-announce-ip to a value whose port (defaulting to the listen Port) differs from all listen endpoint ports; announcing an IP that is not among the bind addresses and is not a wildcard; a multi-endpoint bind where the announce port matches none.
Common situations: NAT/container environments where the announce IP is set correctly but the announce port was overridden to a wrong value; multi-port deployments where the listen endpoints use different ports than the announce; copying cluster config between nodes without updating the announce IP.
Related errors
- Invalid endpoint format {Address} {Port}.
- Gossip sample fraction should be in range [0,100]
- Cannot use AzureStorage device without supplying storage-str
- Cannot use AzureStorage device with both storage-string and
- Incompatible revivification record size and count cardinalit
AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13).
Data as JSON: /api/errors/606a7cd46283e7a7.
Report an issue: GitHub.