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

  1. Set log_schema.message_key to a real field name, e.g. message_key: "message" (or any non-empty path like ".a.b")
  2. Remove the log_schema block entirely to fall back to the default "message" key
  3. 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

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


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