apache/cassandra · critical · ConfigurationException

The seed provider lists no seeds.

Error message

The seed provider lists no seeds.

What it means

After the seed provider is instantiated, applySeedProvider() validates it returns at least one seed. An empty seed list makes cluster bootstrap impossible (a joining node has no contact points), so startup is aborted with this ConfigurationException.

Solutions

  1. Set a non-empty seeds list in cassandra.yaml (at least one live node address host:port)
  2. If seeds come from a template/variable, verify the variable was actually populated in the rendered config before startup
  3. For dynamic seed providers, fix the underlying discovery source (DNS, cloud metadata) or fall back to static seeds

Example fix

// cassandra.yaml before
seed_provider:
  - class_name: org.apache.cassandra.locator.SimpleSeedProvider
    parameters:
      - seeds: ""
// after
seed_provider:
  - class_name: org.apache.cassandra.locator.SimpleSeedProvider
    parameters:
      - seeds: "10.0.1.1:7000"
Defensive patterns

Strategy: validation

Validate before calling

if (conf.seed_provider.parameters.isEmpty() || String.valueOf(conf.seed_provider.parameters.get("seeds")).isBlank())
    throw new IllegalStateException("seed_provider seeds parameter must contain at least one address");

Try / catch

try { DatabaseDescriptor.applySeedProvider(); } catch (ConfigurationException e) { /* supply non-empty seeds */ }

Prevention

When it happens

Trigger: applySeedProvider() called when seedProvider.getSeeds().isEmpty() — e.g. seeds parameter is an empty string, contains only whitespace, or a custom provider returns an empty set (e.g. dynamic provider with no resolvable entries).

Common situations: seed_provider parameters with `seeds: ""` produced by a templating engine with unset variables; environment-variable substitution failing at deploy time; custom seed provider (e.g. cloud-auto-discovery) returning nothing because metadata API or DNS lookup failed.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/java/org/apache/cassandra/config/DatabaseDescriptor.java:1678

    {
        // load the seeds for node contact points
        if (conf.seed_provider == null)
        {
            throw new ConfigurationException("seeds configuration is missing; a minimum of one seed is required.", false);
        }
        try
        {
            Class<? extends SeedProvider> seedProviderClass =
                FBUtilities.classForNameWithoutInitialization(conf.seed_provider.class_name, "seed provider", SeedProvider.class);
            seedProvider = (SeedProvider) seedProviderClass.getConstructor(Map.class).newInstance(conf.seed_provider.parameters);
        }
        // there are about 5 checked exceptions that could be thrown here.
        catch (Exception e)
        {
            throw new ConfigurationException(e.getMessage() + "\nFatal configuration error; unable to start server.  See log for stacktrace.", true);
        }
        if (seedProvider.getSeeds().size() == 0)
            throw new ConfigurationException("The seed provider lists no seeds.", false);
    }

    @VisibleForTesting
    static void checkForLowestAcceptedTimeouts(Config conf)
    {
        if (conf.read_request_timeout.toMilliseconds() < LOWEST_ACCEPTED_TIMEOUT.toMilliseconds())
        {
            logInfo("read_request_timeout", conf.read_request_timeout, LOWEST_ACCEPTED_TIMEOUT);
            conf.read_request_timeout = new DurationSpec.LongMillisecondsBound("10ms");
        }

        if (conf.range_request_timeout.toMilliseconds() < LOWEST_ACCEPTED_TIMEOUT.toMilliseconds())
        {
            logInfo("range_request_timeout", conf.range_request_timeout, LOWEST_ACCEPTED_TIMEOUT);
            conf.range_request_timeout = new DurationSpec.LongMillisecondsBound("10ms");
        }

        if (conf.request_timeout.toMilliseconds() < LOWEST_ACCEPTED_TIMEOUT.toMilliseconds())

View on GitHub (pinned to 88fd0f6a0e)