vectordotdev/vector · critical
valid message key
Error message
valid message key
What it means
LogSchema::owned_message_path() (lib/vector-core/src/config/log_schema.rs) unwraps the configured message_key path with expect("valid message key"). message_key is an OptionalTargetPath; when the user sets log_schema.message_key to something that parses to no path (an empty string "" in vector.yaml/toml), path becomes None and every component that caches the message path (sources inserting the raw log line, remap, etc.) panics on startup or first use.
Source
Thrown at lib/vector-core/src/config/log_schema.rs:130
pub fn message_key(&self) -> Option<&OwnedValuePath> {
self.message_key.path.as_ref().map(|key| &key.path)
}
/// Returns an `OwnedTargetPath` of the message key.
/// This parses the path and will panic if it is invalid.
///
/// This should only be used where the result will either be cached,
/// or performance isn't critical, since this requires memory allocation.
///
/// # Panics
///
/// Panics if the path in `self.message_key` is invalid.
pub fn owned_message_path(&self) -> OwnedTargetPath {
self.message_key
.path
.as_ref()
.expect("valid message key")
.clone()
}
pub fn timestamp_key(&self) -> Option<&OwnedValuePath> {
self.timestamp_key.as_ref().map(|key| &key.path)
}
pub fn host_key(&self) -> Option<&OwnedValuePath> {
self.host_key.as_ref().map(|key| &key.path)
}
pub fn source_type_key(&self) -> Option<&OwnedValuePath> {
self.source_type_key.as_ref().map(|key| &key.path)
}
pub fn metadata_key(&self) -> Option<&OwnedValuePath> {
self.metadata_key.as_ref().map(|key| &key.path)
}View on GitHub (pinned to 3708c39b12)
Solutions
- Set log_schema.message_key to a real field name, e.g. message_key: "message" (or any non-empty path like ".a.b")
- Remove the log_schema block entirely to fall back to the default "message" key
- If the intent was to stop Vector from setting a message field, check for duplicate/empty keys in the generated config rather than blanking the value
Example fix
# before (vector.yaml) log_schema: message_key: "" # after log_schema: message_key: "message"
Defensive patterns
Strategy: validation
Validate before calling
// Before startup, validate the schema override parses to a real path
let schema: LogSchema = config.log_schema.clone().unwrap_or_default();
if let Some(override_key) = &config.log_schema {
assert!(override_key.message_key().is_some(),
"log_schema.message_key must be a non-empty path");
} Type guard
fn has_message_path(schema: &LogSchema) -> bool {
schema.message_key().is_some()
} Try / catch
// Config-level: fail fast with a clear message instead of letting components panic
if config.log_schema.as_ref().is_some_and(|s| s.message_key().is_none()) {
return Err(ConfigError::new("log_schema.message_key must not be empty"));
} Prevention
- Never blank log_schema keys to 'disable' a field; omit the key or block instead
- Lint generated configs for empty-string schema keys before deploy
- Test startup with vector validate --no-environment <config>
When it happens
Trigger: Setting log_schema: message_key: "" (or a value that parses to an empty path) in the config, then running Vector: components calling log_schema().owned_message_path() panic immediately. A default config never hits it because the default key is the non-empty "message".
Common situations: Users who deliberately blank out the message key trying to 'disable' the message field; config-generation tooling that emits an empty message_key value; copying a log_schema block from another config where the key was commented or emptied.
Related errors
- No ability to glob
- %ProgramFiles% environment variable must be defined
- registered log schema required
- valid message key
- failed to read glob pattern
AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20).
Data as JSON: /api/errors/584ed9bab9c41a60.
Report an issue: GitHub.