apache/cassandra · critical · IllegalArgumentException

Found no candidates during initialization. Check if the seed

Error message

Found no candidates during initialization. Check if the seeds are up: %s

What it means

Startup.initializeForDiscovery needs a starting candidate endpoint (the lowest, deterministic pick) to begin cluster discovery. If no candidate option is present and this node is not itself a seed (its broadcast address is not in DatabaseDescriptor.getSeeds()), there is nobody to discover from, so it throws IllegalArgumentException 'Found no candidates during initialization. Check if the seeds are up'. This means a non-seed node has no reachable seed to bootstrap discovery against.

Source

Thrown at src/java/org/apache/cassandra/tcm/Startup.java:442

     * it is aware of. After discovery, the node with a smallest ip address will move to propose itself as
     * a CMS initiator, and attempt to establish a CMS in via two-phase commit protocol.
     */
    public static void initializeForDiscovery(Runnable initMessaging)
    {
        initMessaging.run();
        logger.debug("Discovering other nodes in the system");
        Discovery.DiscoveredNodes candidates = Discovery.instance.discover();
        if (candidates.kind() == Discovery.DiscoveredNodes.Kind.KNOWN_PEERS)
        {
            logger.debug("Got candidates: " + candidates);
            Optional<InetAddressAndPort> option = candidates.nodes().stream().min(InetAddressAndPort::compareTo);
            InetAddressAndPort min;
            if (!option.isPresent())
            {
                if (DatabaseDescriptor.getSeeds().contains(FBUtilities.getBroadcastAddressAndPort()))
                    min = FBUtilities.getBroadcastAddressAndPort();
                else
                    throw new IllegalArgumentException(String.format("Found no candidates during initialization. Check if the seeds are up: %s", DatabaseDescriptor.getSeeds()));
            }
            else
            {
                min = option.get();
            }

             // identify if you need to start the vote
            if (min.equals(FBUtilities.getBroadcastAddressAndPort()) || FBUtilities.getBroadcastAddressAndPort().compareTo(min) < 0)
            {
                Election.instance.nominateSelf(candidates.nodes(),
                                               Collections.singleton(FBUtilities.getBroadcastAddressAndPort()),
                                               ClusterMetadata.current(),
                                               false);
            }
        }

        while (!ClusterMetadata.current().epoch.isAfter(Epoch.FIRST))
        {

View on GitHub (pinned to 88fd0f6a0e)

Solutions

  1. Ensure cassandra.yaml seeds lists at least one reachable, up-to-date seed for the cluster.
  2. If this node should form a new cluster, add its own broadcast address to the seeds list.
  3. Verify seed hostnames resolve and are reachable (ping/nc) before restart.
  4. Start the seed nodes first, then the non-seed node.
  5. Check startup logs for DNS/connection failures against each seed to pinpoint the unreachable one.

Example fix

# before: empty seeds on a joining node
seed_provider:
  - seeds: []
# after: list live seeds
seed_provider:
  - class_name: org.apache.cassandra.locator.SimpleSeedProvider
    parameters:
      - seeds: "10.0.0.1:7000,10.0.0.2:7000"
Defensive patterns

Strategy: validation

Validate before calling

// pre-start check: a non-seed node must have at least one reachable seed
if (!DatabaseDescriptor.getSeeds().contains(FBUtilities.getBroadcastAddressAndPort())
    && DatabaseDescriptor.getSeeds().isEmpty())
    throw new ConfigurationException("Non-seed node requires a configured seed");

Try / catch

try { Startup.initializeForDiscovery(...); }
catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Found no candidates")) {
        // fix seeds in cassandra.yaml, confirm seeds are up, restart
    } else throw e;
}

Prevention

When it happens

Trigger: initializeForDiscovery resolves no candidate endpoint: DatabaseDescriptor.getSeeds() does not contain this node's broadcast address and the optional candidate is empty (no seeds configured or none resolvable); a non-seed node starts with an empty/invalid seed list.

Common situations: Fresh node started with seeds left empty; all configured seeds are down or DNS-unresolvable at startup; hostname-based seeds that fail resolution; node misconfigured as non-seed but expected to form a new cluster.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10). Data as JSON: /api/errors/629b8cb26852e7a9. Report an issue: GitHub.