quickwit-oss/quickwit · error

failed to parse Kafka client parameters. `client_params` mus

Error message

failed to parse Kafka client parameters. `client_params` must be a JSON object

What it means

The Kafka source accepts a `client_params` JSON value that must be a JSON object of librdkafka settings. `parse_client_params` bails when the provided value is any other JSON type (string, array, number, etc.).

Source

Thrown at quickwit/quickwit-indexing/src/source/kafka_source.rs:712

        Some("info") | None => RDKafkaLogLevel::Info,
        Some("warn") | Some("warning") => RDKafkaLogLevel::Warning,
        Some("error") => RDKafkaLogLevel::Error,
        Some("critical") => RDKafkaLogLevel::Critical,
        Some("alert") => RDKafkaLogLevel::Alert,
        Some("emerg") => RDKafkaLogLevel::Emerg,
        Some(level) => bail!(
            "failed to parse Kafka client log level. value `{}` is not supported",
            level
        ),
    };
    Ok(log_level)
}

fn parse_client_params(client_params: JsonValue) -> anyhow::Result<ClientConfig> {
    let params = if let JsonValue::Object(params) = client_params {
        params
    } else {
        bail!("failed to parse Kafka client parameters. `client_params` must be a JSON object");
    };
    let mut client_config = ClientConfig::new();
    for (key, value_json) in params {
        let value = match value_json {
            JsonValue::Bool(value_bool) => value_bool.to_string(),
            JsonValue::Number(value_number) => value_number.to_string(),
            JsonValue::String(value_string) => value_string,
            JsonValue::Null => continue,
            JsonValue::Array(_) | JsonValue::Object(_) => bail!(
                "failed to parse Kafka client parameters. `client_params.{}` must be a boolean, \
                 number, or string",
                key
            ),
        };
        client_config.set(key, value);
    }
    Ok(client_config)
}

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Make `client_params` a JSON object with string keys: `{"group.id": "...", "security.protocol": "SSL"}`.
  2. If passing through templating/tooling, unescape the JSON so it is an object, not a string.
  3. Validate the source config JSON before submitting (e.g., `jq .client_params source.json`).

Example fix

// before
"client_params": "{\"group.id\":\"qw-group\"}"
// after
"client_params": { "group.id": "qw-group" }
Defensive patterns

Strategy: type-guard

Validate before calling

// JS
if (typeof params.client_params !== 'object' || Array.isArray(params.client_params)) throw new Error('client_params must be a JSON object');

Type guard

function isJsonObject(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }

Try / catch

// Rust caller
let params: serde_json::Value = serde_json::from_str(raw)?;
if !params.is_object() { bail!("client_params must be a JSON object"); }

Prevention

When it happens

Trigger: `create_consumer` or `check_connectivity` receives a source whose `client_params` is a valid JSON but not an object (e.g., a quoted JSON string or an array).

Common situations: Double-encoding: embedding a JSON object as a string (`"client_params": "{\"group.id\":\"x\"}"`); pasting a YAML-style list; config template rendered incorrectly.

Understand the failure class

Related errors


AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08). Data as JSON: /api/errors/623435565c3d3d9d. Report an issue: GitHub.