vectordotdev/vector · error

UNSUPPORTED_DYNAMIC_FEATURE_SELECTOR

Error message

UNSUPPORTED_DYNAMIC_FEATURE_SELECTOR

What it means

from_config scans the `type` field of every component under enrichment_tables, secret, sources, transforms, and sinks; if any type string contains a dynamic reference (template/condition syntax rather than a literal component type), it bails with UNSUPPORTED_DYNAMIC_FEATURE_SELECTOR. Static analysis of the config cannot map a dynamic type to concrete cargo features.

Solutions

  1. Replace the dynamic type expression with the literal component type string
  2. Pre-render the templated config to a static one before running feature extraction
  3. Split the config so each component has a concrete, static `type`

Example fix

// before
sinks:
  out:
    type: ${SINK_TYPE}
// after
sinks:
  out:
    type: console
Defensive patterns

Strategy: validation

Validate before calling

fn is_static_type(cfg: &serde_yaml::Value) -> bool {
    cfg.get("sinks").map(|s| s.as_mapping().map(|m| m.values().all(|c|
        c.get("type").and_then(|t| t.as_str()).map(|ts| !ts.contains("${") && !ts.contains("{{")).unwrap_or(false)
    )).unwrap_or(false)).unwrap_or(false)
}

Prevention

When it happens

Trigger: Calling load_and_extract where a component's `type` uses dynamic interpolation or a conditional expression (has_dynamic_reference match) instead of a fixed string like "console".

Common situations: Programmatically generated configs with templated component types; hand-written configs that accidentally left a placeholder (e.g. "${SINK_TYPE}") in a type field.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/a91920eae66f063b. Report an issue: GitHub.

Appendix: source

Thrown at vdev/src/utils/features.rs:168

    }
}

fn from_config(config: &FeatureConfig, declared_features: &FeatureSet) -> Result<Vec<String>> {
    if config.provider.is_some() {
        bail!(UNSUPPORTED_PROVIDER);
    }
    if [
        &config.enrichment_tables,
        &config.secret,
        &config.sources,
        &config.transforms,
        &config.sinks,
    ]
    .into_iter()
    .flat_map(|section| section.values())
    .any(|component| has_dynamic_reference(&component.r#type))
    {
        bail!(UNSUPPORTED_DYNAMIC_FEATURE_SELECTOR);
    }
    let mut features = FeatureSet::default();
    add_option(&mut features, "api", config.api.as_ref());

    get_features(
        &mut features,
        "enrichment-tables",
        &config.enrichment_tables,
        declared_features,
    );
    get_features(&mut features, "secrets", &config.secret, declared_features);
    get_features(&mut features, "sources", &config.sources, declared_features);
    get_features(
        &mut features,
        "transforms",
        &config.transforms,
        declared_features,
    );

View on GitHub (pinned to bdb87aeaa4)