vectordotdev/vector · error
Invalid filename , unknown extension
Error message
Invalid filename {}, unknown extension What it means
After picking a parser by extension, load_and_extract rejects any extension other than json, toml, yaml, or yml with this message. The tool has no deserializer registered for other formats, so files like .xml, .conf, or .cfg cannot be interpreted as a FeatureConfig.
Solutions
- Convert the config to one of the supported formats (YAML recommended) and use the matching extension
- Fix the extension typo (.tml → .toml, .yamle → .yaml)
- Filter the input file list to supported extensions before processing
Example fix
// before
load_and_extract(Path::new("config/features.ini"))?;
// after
load_and_extract(Path::new("config/features.toml"))?; Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED: [&str; 4] = ["json", "toml", "yaml", "yml"];
fn supported(p: &Path) -> bool {
p.extension().and_then(|e| e.to_str()).map(|e| SUPPORTED.contains(&e.to_lowercase().as_str())).unwrap_or(false)
} Prevention
- Convert foreign formats (ini, xml) to YAML/TOML before feature extraction
- Watch for extension typos in scripts (.tml, .yamle)
- Restrict directory scans to *.json, *.toml, *.yaml, *.yml
When it happens
Trigger: Calling load_and_extract with paths like "config.xml", "features.ini", or any extension outside {json, toml, yaml, yml}.
Common situations: Pointing the feature-extraction tool at a different tool's config format; a typo such as .yamle or .tml; batch-processing a directory that mixes in unrelated file types.
Related errors
- Invalid filename , no extension
- Failed to bind to listener socket at path
- Failed to create output dir
- Failed to create output dir(s)
- Failed to get entry for dir
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/5f0d611efa02fc00.
Report an issue: GitHub.
Appendix: source
Thrown at vdev/src/utils/features.rs:131
.with_context(|| format!("failed to read {}", filename.display()))?;
let config: FeatureConfig = match filename
.extension()
.and_then(OsStr::to_str)
.map(str::to_lowercase)
.as_deref()
{
None => bail!("Invalid filename {}, no extension", filename.display()),
Some("json") => serde_json::from_str(&config)?,
Some("toml") => toml::from_str(&config)?,
Some("yaml" | "yml") => {
let value: serde_yaml::Value = serde_yaml::from_str(&config)?;
if contains_yaml_merge_key(&value) {
bail!(UNSUPPORTED_YAML_MERGE_KEY);
}
serde_yaml::from_value(value)?
}
Some(_) => bail!("Invalid filename {}, unknown extension", filename.display()),
};
let declared_features = CargoToml::load_from(&find_repo_root()?.join("Cargo.toml"))?
.features
.into_keys()
.collect();
from_config(&config, &declared_features)
}
fn contains_yaml_merge_key(value: &serde_yaml::Value) -> bool {
match value {
serde_yaml::Value::Sequence(values) => values.iter().any(contains_yaml_merge_key),
serde_yaml::Value::Mapping(mapping) => mapping
.iter()
.any(|(key, value)| key.as_str() == Some("<<") || contains_yaml_merge_key(value)),
serde_yaml::Value::Tagged(tagged) => contains_yaml_merge_key(&tagged.value),
_ => false,View on GitHub (pinned to bdb87aeaa4)