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

  1. Ensure ClusterAnnouncePort matches the port of one of your listen endpoints (or leave it 0 to default to Port).
  2. Set ClusterAnnounceIp to an address that is either one of your bind addresses or matches a wildcard bind (0.0.0.0/::).
  3. 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.
  4. 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

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


AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13). Data as JSON: /api/errors/606a7cd46283e7a7. Report an issue: GitHub.