risingwavelabs/risingwave · error

protobuf key is not supported

Error message

protobuf key is not supported

What it means

The Protobuf parser only supports decoding the message payload; a `key_message_name` in the Protobuf encoding config means a key schema was configured, which is rejected up front. Per Confluent schema-registry best practices, key and value are separate schemas and RisingWave's protobuf source path does not implement key decoding.

Source

Thrown at src/connector/src/parser/protobuf/parser.rs:117

    }
}

#[derive(Debug, Clone)]
pub struct ProtobufParserConfig {
    wire_type: WireType,
    pub(crate) message_descriptor: MessageDescriptor,
    messages_as_jsonb: HashSet<String>,
}

impl ProtobufParserConfig {
    pub async fn new(encoding_properties: EncodingProperties) -> ConnectorResult<Self> {
        let protobuf_config = try_match_expand!(encoding_properties, EncodingProperties::Protobuf)?;
        let message_name = &protobuf_config.message_name;

        let wire_type = (&protobuf_config.schema_location).try_into()?;
        if protobuf_config.key_message_name.is_some() {
            // https://docs.confluent.io/platform/7.5/control-center/topics/schema.html#c3-schemas-best-practices-key-value-pairs
            bail!("protobuf key is not supported");
        }
        let pool = match protobuf_config.schema_location {
            SchemaLocation::Confluent {
                urls,
                client_config,
                name_strategy,
                topic,
            } => {
                let url = handle_sr_list(urls.as_str())?;
                let client = Client::new(url, &client_config)?;
                let loader = SchemaLoader::Confluent(ConfluentSchemaLoader {
                    client,
                    name_strategy,
                    topic,
                    key_record_name: None,
                    val_record_name: Some(message_name.clone()),
                });
                let (_schema_id, root_file_descriptor) = loader

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Remove `key_message_name` (and key-schema settings) from the protobuf encoding config and recreate the source.
  2. Encode all needed identifying fields inside the value message instead of the protobuf key.
  3. If the key is needed, use JSON key encoding or another supported mechanism.
  4. Check the source creation SQL / with-options and strip key-schema entries.

Example fix

-- before
... FORMAT ENCODE PROTOBUF (message = 'Enveloped', key.message = 'Key', schema.location = '...')
-- after
... FORMAT ENCODE PROTOBUF (message = 'Enveloped', schema.location = '...')
Defensive patterns

Strategy: validation

Validate before calling

// Reject protobuf configs with a key schema before creating the source:
if protobuf_config.key_message_name.is_some() {
    return Err("protobuf key is not supported; remove key.message from with-options");
}

Try / catch

match create_source(sql) {
    Err(e) if e.to_string().contains("protobuf key is not supported") => {
        // strip key.message option and retry
    }
    other => other?,
}

Prevention

When it happens

Trigger: `ProtobufParser::new` checks `protobuf_config.key_message_name.is_some()` while building the parser from `EncodingProperties::Protobuf` — any source/MV created with protobuf encoding that specifies a key message name (key schema) bails immediately at creation time.

Common situations: Copying a Debezium/Confluent protobuf config that includes a key message name; a generated config template that always sets `key_message_name`; confusion between Kafka message key handling and protobuf key schema support.

Related errors


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