databendlabs/databend · error · InvalidData

{message}

Error message

{message}

What it means

The meta-service's invalid_reply constructor builds an InvalidReply error carrying an arbitrary message. It is raised whenever a meta API handler receives a reply whose shape/content is not what the caller expects (e.g. a reply variant that does not match the request, or missing fields). The message is embedded in both the error text and an io::Error of kind InvalidData used as its source.

Solutions

  1. Read the error message to see which reply field or variant was unexpected.
  2. Check for mixed meta-node versions in the cluster and upgrade nodes to the same release.
  3. Inspect the meta handler for the failing API to ensure it returns the reply variant matching the request (e.g. correct CreateLockRevReply fields).
  4. Retry the operation if it followed a leadership change / transient Raft state; verify cluster health with the meta admin API.
Defensive patterns

Strategy: retry

Validate before calling

// no pre-call check possible; validate reply shape after the call instead
if !matches!(reply, MetaReply::ListLockRevisions(_)) {
    return Err(invalid_reply(format!("expect list_lock_revisions reply, got {reply:?}")));
}

Try / catch

match meta_api.list_locks_v2(&ident).await {
    Err(KVAppError::InvalidReply(e)) if is_transient(&e) => {
        // retry once after a leadership/state change
        tokio::time::sleep(RETRY_DELAY).await;
        meta_api.list_locks_v2(&ident).await
    }
    other => other,
}

Prevention

When it happens

Trigger: Any meta API path that validates replies — list_lock_revisions_v2, create_lock_revision_v2, CreateLockRevReply construction, list_locks_v2, get_mv_definition_snapshot, list_segment_claims — receiving a reply message of the wrong type or with missing/invalid content, producing a call like invalid_reply(format!(...)).

Common situations: Mixed-version meta clusters where an older node returns a reply format a newer caller cannot interpret; a handler returning the wrong reply variant for a request; Raft/KV state desynchronized so an expected key or record is absent from the reply.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/10cef0a60d4bf093. Report an issue: GitHub.

Appendix: source

Thrown at src/meta/api/src/error/constructors.rs:33

use std::fmt::Display;
use std::io;

use databend_common_meta_app::app_error::AppError;
use databend_common_meta_app::app_error::DatabaseAlreadyExists;
use databend_common_meta_app::app_error::TableAlreadyExists;
use databend_common_meta_app::app_error::UnknownDatabase;
use databend_common_meta_app::app_error::UnknownDatabaseId;
use databend_common_meta_app::app_error::UnknownTable;
use databend_common_meta_app::schema::TableNameIdent;
use databend_common_meta_app::schema::database_name_ident::DatabaseNameIdent;
use databend_meta_client::types::InvalidReply;

use super::app_error::KVAppError;

pub(crate) fn invalid_reply<M>(message: M) -> InvalidReply
where M: Display {
    let message = message.to_string();
    let source = io::Error::new(io::ErrorKind::InvalidData, message.clone());
    InvalidReply::new(message, &source)
}

pub fn unknown_database_error(db_name_ident: &DatabaseNameIdent, msg: impl Display) -> AppError {
    let e = UnknownDatabase::new(
        db_name_ident.database_name(),
        format!("{}: {}", msg, db_name_ident.display()),
    );
    AppError::UnknownDatabase(e)
}

pub fn db_has_to_exist(
    seq: u64,
    db_name_ident: &DatabaseNameIdent,
    msg: impl Display,
) -> Result<(), KVAppError> {
    if seq == 0 {
        Err(KVAppError::AppError(unknown_database_error(

View on GitHub (pinned to 288d84d76e)