risingwavelabs/risingwave · error · SinkError

`Delete` operation is not supported in `append_only` mode

Error message

`Delete` operation is not supported in `append_only` mode

What it means

The Elasticsearch/OpenSearch sink formatter is operating in append-only mode (is_append_only), which only supports INSERT operations. When an Op::Delete row arrives in a chunk, the formatter rejects it because append-only mode cannot express document deletions. The chunk conversion returns an error instead of producing a bulk request.

Source

Thrown at src/connector/src/sink/elasticsearch_opensearch/elasticsearch_opensearch_formatter.rs:197

                                } else {
                                    modified_col_indices.push(index);
                                }
                            });
                    }
                    let value = self
                        .value_encoder
                        .encode_cols(rows, modified_col_indices.into_iter())?;
                    result_vec.push(BuildBulkPara {
                        index: index.to_owned(),
                        key,
                        value: Some(value),
                        mem_size_b: rows.value_estimate_size(),
                        routing_column,
                    });
                }
                Op::Delete => {
                    if is_append_only {
                        return Err(SinkError::ElasticSearchOpenSearch(anyhow!(
                            "`Delete` operation is not supported in `append_only` mode"
                        )));
                    }
                    let key = self.key_encoder.encode(rows)?.into_string()?;
                    let mem_size_b = std::mem::size_of_val(&key);
                    result_vec.push(BuildBulkPara {
                        index: index.to_owned(),
                        key,
                        value: None,
                        mem_size_b,
                        routing_column,
                    });
                }
                Op::UpdateDelete => {
                    if is_append_only {
                        return Err(SinkError::ElasticSearchOpenSearch(anyhow!(
                            "`UpdateDelete` operation is not supported in `append_only` mode"
                        )));

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Remove `append_only = true` from the sink options so the sink runs in upsert/debezium mode and can encode deletes.
  2. Only sink append-only streams (e.g., a fact stream that never retracts) when keeping append_only mode.
  3. Pre-filter retracting events upstream if deletes are not meaningful for the target index.

Example fix

// before
CREATE SINK s FROM mv WITH (connector='elasticsearch', append_only=true);
// after
CREATE SINK s FROM mv WITH (connector='elasticsearch', primary_key='id');
Defensive patterns

Strategy: validation

Validate before calling

-- confirm the stream is truly append-only before using append_only=true
SHOW MATERIALIZED VIEWS; -- check the source relation never retracts (no UPDATE/DELETE)

Try / catch

match err { SinkError::ElasticSearchOpenSearch(msg) if msg.contains("`Delete` operation is not supported") => recreate_sink_without_append_only(), _ => return Err(err) }

Prevention

When it happens

Trigger: convert_chunk encounters a row with Op::Delete while the sink was created in append-only mode (e.g., sink created with `append_only=true` against a stream that emits deletes, such as an upsert MV or BACKFILL/UPDATE operations).

Common situations: Users sink a materialized view that undergoes updates/deletes into an ES sink declared append_only; or schema changes/upstream retracts generate Delete rows unexpectedly.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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