vectordotdev/vector · error

Sink not present

Error message

Sink not present

What it means

During `vector validate` (or config validation at startup), healthchecks returned by topology::take_healthchecks are executed one by one; after a healthcheck future succeeds, the code looks the component back up with config.sink(&id).expect("Sink not present") to read its healthcheck.enabled setting. The expect() encodes the invariant that every healthcheck id corresponds to a configured sink. If an id has no matching sink entry, this expect panics and crashes the validate run. In released Vector the invariant holds (healthchecks are built from the config's sinks), so hitting this means an internal bug or a version skew between config parsing and topology building.

Source

Thrown at src/validate.rs:362

        return !opts.deny_warnings;
    }

    let healthchecks = topology::take_healthchecks(diff, pieces);
    // We are running health checks in serial so it's easier for the users
    // to parse which errors/warnings/etc. belong to which healthcheck.
    let mut validated = true;
    for (id, healthcheck) in healthchecks {
        let mut failed = |error| {
            validated = false;
            fmt.error(error);
        };

        trace!("Healthcheck for {id} starting.");
        match tokio::spawn(healthcheck).await {
            Ok(Ok(_)) => {
                if config
                    .sink(&id)
                    .expect("Sink not present")
                    .healthcheck()
                    .enabled
                {
                    fmt.success(format!("Health check \"{id}\""));
                } else {
                    fmt.warning(format!("Health check disabled for \"{id}\""));
                    validated &= !opts.deny_warnings;
                }
            }
            Ok(Err(e)) => failed(format!("Health check for \"{id}\" failed: {e}")),
            Err(error) if error.is_cancelled() => {
                failed(format!("Health check for \"{id}\" was cancelled"))
            }
            Err(_) => failed(format!("Health check for \"{id}\" panicked")),
        }
        trace!("Healthcheck for {id} done.");
    }

View on GitHub (pinned to 3708c39b12)

Solutions

  1. Rerun with `vector validate --skip-healthchecks` (or set healthchecks.enabled = false in the config) to bypass the panicking path and validate the rest of the config.
  2. Check for version mismatch: make sure the `vector` binary executing validate is the version you think (vector --version) and re-run with the matching binary.
  3. If you run a fork/patched Vector, audit topology::take_healthchecks to confirm it only yields ids that exist in config.sinks, and file an issue upstream with the config and panic backtrace.
  4. Report the panic to the Vector maintainers with your config (redacted) and backtrace — stock builds should never hit this.

Example fix

// before (src/validate.rs:360-365)
if config.sink(&id).expect("Sink not present").healthcheck().enabled {
    fmt.success(format!("Health check \"{id}\""));
}

// after — degrade gracefully instead of panicking the validator
match config.sink(&id) {
    Some(sink) if sink.healthcheck().enabled => {
        fmt.success(format!("Health check \"{id}\""));
    }
    Some(_) => {
        fmt.warning(format!("Health check disabled for \"{id}\""));
        validated &= !opts.deny_warnings;
    }
    None => failed(format!("Health check for \"{id}\" has no matching sink")),
}
Defensive patterns

Strategy: validation

Validate before calling

# Avoid the panicking healthcheck path entirely when validating config files
vector validate --skip-healthchecks /etc/vector/vector.yaml

# Or disable healthchecks in the config before validating
grep -q '^healthchecks:' config.yaml || printf '\nhealthchecks:\n  enabled: false\n' >> config.yaml

Prevention

When it happens

Trigger: Running `vector validate` (without --skip-healthchecks) against a config, and a healthcheck id returned by take_healthchecks does not resolve via config.sink(&id). This can only happen if healthchecks were taken for non-sink components or the config object was mutated between building pieces and validating — e.g., a bug in a custom build of Vector, a patched topology module, or source-provided healthchecks not filtered out.

Common situations: Custom forks/embedded Vector-lib where topology::take_healthchecks is extended; running `vector validate` on a config after a partial code upgrade (binary version newer/older than expected config semantics); otherwise virtually unreachable for stock configs — normal bad configs produce 'Health check for X failed' messages instead of this panic.

Related errors


AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20). Data as JSON: /api/errors/dbaec1f5f982c42d. Report an issue: GitHub.