influxdata/influxdb · error · Error
Invalid InfluxQL metadata
Error message
Invalid InfluxQL metadata: {0} What it means
Error::InvalidMetadata wraps a serde_json::Error produced when deserializing InfluxQlMetadata from the Arrow schema metadata map. The metadata key exists but its JSON payload cannot be parsed into the expected struct (via #[from] serde_json::Error), so the formatter reports 'Invalid InfluxQL metadata: {0}'.
Solutions
- Log the raw metadata string and the inner serde_json error to see which field/shape mismatched
- Align client and server versions so InfluxQlMetadata serialization matches on both sides
- Fix the metadata JSON in test fixtures to match the InfluxQlMetadata struct (correct field names and types)
- Catch this variant and fall back to a plain formatter (csv/json) if you only need raw rows, not line protocol
Example fix
// before
// metadata: {"measurement": "cpu"} // missing required fields
let out = formatter.format(&batches)?;
// after
// metadata: {"measurement": "cpu", "tag_keys": ["host"], "field_keys": ["usage"]}
let out = formatter.format(&batches)?; Defensive patterns
Strategy: try-catch
Validate before calling
fn metadata_is_valid_json(batches: &[RecordBatch], key: &str) -> bool {
batches.first()
.and_then(|b| b.schema().metadata().get(key))
.map(|v| serde_json::from_str::<serde_json::Value>(v).is_ok())
.unwrap_or(false)
} Type guard
fn is_invalid_metadata(e: &influxql_format::Error) -> bool {
matches!(e, influxql_format::Error::InvalidMetadata(_))
} Try / catch
match formatter.format(&batches) {
Err(influxql_format::Error::InvalidMetadata(src)) => {
eprintln!("metadata JSON parse failed: {src}; falling back to csv");
csv_formatter.format(&batches)?;
}
other => other?,
} Prevention
- Fix test fixture metadata to match InfluxQlMetadata field names/types exactly
- Pin matching client/server versions to avoid metadata schema drift
- Log the raw metadata payload when deserialization fails
When it happens
Trigger: Formatting batches whose schema metadata contains an InfluxQlMetadata value that is not valid JSON or does not match the InfluxQlMetadata struct fields — e.g., payload produced by an incompatible server version or manually written test metadata.
Common situations: Client and server version skew (metadata JSON schema changed between IOx releases); hand-crafting the metadata entry with wrong field names/types; metadata string corrupted by an intermediary proxy rewriting headers/annotations.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19).
Data as JSON: /api/errors/bfc9ff7d5c5d7f03.
Report an issue: GitHub.
Appendix: source
Thrown at core/influxdb_iox_client/src/format/influxql.rs:24
use comfy_table::{Cell, Table};
use generated_types::influxdata::iox::querier::v1::InfluxQlMetadata;
use std::io::Write;
use std::iter;
use thiserror::Error;
/// Error type for results formatting
#[derive(Debug, Error)]
pub enum Error {
/// Arrow error.
#[error("Arrow error: {}", .0)]
Arrow(ArrowError),
/// [`InfluxQlMetadata`] not found in Arrow schema metadata.
#[error("Missing InfluxQL metadata")]
MissingMetadata,
/// Error deserializing [`InfluxQlMetadata`] from Arrow schema metadata.
#[error("Invalid InfluxQL metadata: {0}")]
InvalidMetadata(#[from] serde_json::Error),
/// Error writing formatted output.
#[error("Error writing output: {0}")]
Write(#[from] std::io::Error),
}
type Result<T, E = Error> = std::result::Result<T, E>;
/// Options for controlling how table borders are rendered.
#[derive(Debug, Default, Clone, Copy)]
pub enum TableBorders {
/// Use ASCII characters.
#[default]
Ascii,
/// Use UNICODE box-drawing characters.
Unicode,
/// Do not render borders.
None,View on GitHub (pinned to 06200ef96b)