risingwavelabs/risingwave · error · ErrorResp

confluent schema registry error {error_code}: {message}

Error message

confluent schema registry error {error_code}: {message}

What it means

ErrorResp is the deserialized error body returned by the Confluent Schema Registry REST API; as a thiserror error it renders as 'confluent schema registry error {error_code}: {message}'. It surfaces a server-side registry error (e.g. 40401 SubjectNotFound, 409 Conflict, 42201 Invalid schema) with the registry's own error code and message.

Source

Thrown at src/connector/src/schema/schema_registry/util.rs:182

#[derive(Debug, Deserialize)]
pub struct GetByIdResp {
    pub schema: String,
}

#[derive(Debug, Deserialize)]
pub struct GetBySubjectResp {
    pub id: i32,
    pub schema: String,
    pub version: i32,
    pub subject: String,
    // default to empty/non-reference
    #[serde(default)]
    pub references: Vec<SchemaReference>,
}

/// <https://docs.confluent.io/platform/7.5/schema-registry/develop/api.html#errors>
#[derive(Debug, Deserialize, thiserror::Error)]
#[error("confluent schema registry error {error_code}: {message}")]
pub struct ErrorResp {
    error_code: i32,
    message: String,
}

#[cfg(test)]
mod test {
    use super::super::handle_sr_list;

    #[test]
    fn test_handle_sr_list() {
        let addr1 = "http://localhost:8081".to_owned();
        assert_eq!(
            handle_sr_list(&addr1).unwrap(),
            vec!["http://localhost:8081".parse().unwrap()]
        );

        let addr2 = "http://localhost:8081,http://localhost:8082".to_owned();

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Look up the numeric error_code in the Confluent API docs to identify the exact condition (40401 subject not found, 40901 incompatible schema, etc.).
  2. Verify the client points at the same registry that the producer registered schemas with.
  3. Check the subject exists: GET /subjects and GET /subjects/{subject}/versions.
  4. If the registry lost the schema (recreated), re-register the schema or repopulate IDs; fix incompatibilities by enabling/adjusting compatibility settings.

Example fix

// before: wrong registry in sink/source
schema.registry = 'http://new-registry:8081'  # schema IDs missing here
// after: point at the registry holding the schemas
schema.registry = 'http://original-registry:8081'
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-check subject exists before operations
let subjects: Vec<String> = reqwest::get(format!("{}/subjects", registry_url))
    .await?.json().await?;
assert!(subjects.contains(&subject), "subject {} not found", subject);

Try / catch

match req_inner(&ctx).await {
    Ok(v) => v,
    Err(RequestError::Unsuccessful(resp)) => {
        tracing::error!(code = resp.error_code, msg = %resp.message, "registry rejected request");
        match resp.error_code {
            40401 => handle_subject_not_found(),
            _ => return Err(resp.into()),
        }
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Any registry HTTP call that receives a non-success JSON error body which deserializes into ErrorResp — e.g. requesting a schema ID not present in the registry, registering an incompatible schema, or referencing an unknown subject/version.

Common situations: Schema ID from Kafka messages does not exist in the configured registry (wrong registry or registry recreated), schema incompatibility on registration, subject deleted (soft delete), or API auth returning registry-level errors.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/548a4f77a0acb615. Report an issue: GitHub.