risingwavelabs/risingwave · error · SinkError::Config

HTTP sink requires url option when schema has exactly 1 colu

Error message

HTTP sink requires url option when schema has exactly 1 column

What it means

When the sink schema has exactly one column, that column is treated as the payload and the target URL must come from the `url` option rather than a url column; if no `url` option was provided, configuration is invalid.

Source

Thrown at src/connector/src/sink/http.rs:127

            "HTTP sink only supports append-only mode"
        )));
    }

    let method = match method {
        None => reqwest::Method::POST,
        Some(method) if method.eq_ignore_ascii_case("POST") => reqwest::Method::POST,
        Some(method) if method.eq_ignore_ascii_case("PUT") => reqwest::Method::PUT,
        Some(method) => {
            return Err(SinkError::Config(anyhow!(
                "HTTP sink method must be POST or PUT, got '{method}'"
            )));
        }
    };

    let fields = schema.fields();
    let (payload_index, url, payload_type) = if fields.len() == 1 {
        let Some(url) = url else {
            return Err(SinkError::Config(anyhow!(
                "HTTP sink requires url option when schema has exactly 1 column"
            )));
        };
        let url = url
            .parse()
            .context("invalid URL")
            .map_err(SinkError::Config)?;
        (0, HttpUrl::Static(url), fields[0].data_type.clone())
    } else {
        for field in fields {
            match field.name.as_str() {
                HTTP_SINK_PAYLOAD_COLUMN | HTTP_SINK_URL_COLUMN => {}
                _ => {
                    return Err(SinkError::Config(anyhow!(
                        "HTTP sink with multiple columns only supports payload and url columns, got {}",
                        field.name
                    )));
                }

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Add url='http://...' to the sink WITH options
  2. Or add a second column named per the url-column convention so per-row URLs are used
  3. Verify the schema of the streamed relation matches your intent

Example fix

// before
CREATE SINK s FROM mv WITH (connector='http');
// after
CREATE SINK s FROM mv WITH (connector='http', url='http://example.com/hook');
Defensive patterns

Strategy: validation

Validate before calling

// ensure single-column schemas carry a url option
if schema.fields().len() == 1 && !options.contains_key("url") {
    return Err("single-column HTTP sink requires url option".into());
}

Try / catch

match sink::try_create(props) {
    Err(e) if e.to_string().contains("requires url option") => {
        log::error!("add url='...' to WITH clause: {e}");
    }
    r => r?,
}

Prevention

When it happens

Trigger: `validate_http_sink` sees schema.fields().len() == 1 and url == None.

Common situations: Single-column payload MV without specifying url in WITH; user expected the single column to hold a URL but the engine treats it as payload.

Understand the failure class

Background: "Must pass :limit option" / "Missing required option" — required option errors explained — this error's family across 41 libraries.

Related errors


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