influxdata/influxdb · critical

Invalid metadata name

Error message

Invalid metadata name

What it means

Not a typed variant but a `panic!` via `.expect("Invalid metadata name")` in `FlightClient::new`: converting a connection header name to a tonic `MetadataKey` failed. gRPC metadata keys must be valid HTTP/2 header names (visible ASCII, no invalid characters); the expect aborts the process instead of returning an error.

Solutions

  1. Inspect all header names in the IOx Connection config for invalid characters and correct them
  2. Pre-validate names with `MetadataKey::from_bytes(...)` (or `from_str`) and handle the Result instead of relying on expect
  3. Strip or reject non-conforming headers before building the client
  4. Ensure header names are lowercase ASCII per gRPC metadata rules

Example fix

// before
let name = MetadataKey::<_>::from_bytes(name.as_str().as_bytes())
    .expect("Invalid metadata name");
// after
let name = MetadataKey::<_>::from_bytes(name.as_str().as_bytes())
    .map_err(|e| anyhow::anyhow!("invalid metadata name {:?}: {}", name.as_str(), e))?;
Defensive patterns

Strategy: validation

Validate before calling

use tonic::metadata::MetadataKey;
fn valid_metadata_names(headers: &[(String, String)]) -> Result<(), String> {
    for (name, _) in headers {
        MetadataKey::from_bytes(name.as_bytes())
            .map_err(|e| format!("invalid metadata name {:?}: {}", name, e))?;
    }
    Ok(())
}

Type guard

fn is_valid_metadata_key(name: &str) -> bool {
    tonic::metadata::MetadataKey::from_bytes(name.as_bytes()).is_ok()
}

Prevention

When it happens

Trigger: Constructing a FlightClient from an IOx Connection whose headers map contains a name that violates gRPC metadata-key rules (invalid characters, non-ASCII, empty, or illegal header-name bytes).

Common situations: Config files or environment variables supplying header names with spaces, Unicode, or control characters; programmatically built header maps containing typos or placeholder keys.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/bc37ac1cdcfdd684. Report an issue: GitHub.

Appendix: source

Thrown at core/influxdb_iox_client/src/client/flight/mod.rs:210

#[derive(Debug)]
pub struct Client {
    inner: FlightClient,
}

impl Client {
    /// Creates a new client with the provided [`Connection`]. Panics
    /// if the metadata in connection is invalid for the underlying
    /// tonic library.
    pub fn new(connection: Connection) -> Self {
        // Extract headers to include with each request
        let (channel, headers) = connection.into_grpc_connection().into_parts();

        let mut inner = FlightClient::new(channel);

        // Copy any headers from IOx Connection
        for (name, value) in headers.iter() {
            let name = MetadataKey::<_>::from_bytes(name.as_str().as_bytes())
                .expect("Invalid metadata name");

            let value: MetadataValue<_> =
                value.as_bytes().try_into().expect("Invalid metadata value");
            inner.metadata_mut().insert(name, value);
        }

        Self { inner }
    }

    /// Return the inner arrow flight client
    pub fn into_inner(self) -> FlightClient {
        self.inner
    }

    /// Get a mutable reference to the inner arrow flight client
    pub fn inner(&mut self) -> &mut FlightClient {
        &mut self.inner
    }

View on GitHub (pinned to 06200ef96b)