risingwavelabs/risingwave · error · SinkError::Config

HTTP sink requires either url option or url column

Error message

HTTP sink requires either url option or url column

What it means

The HTTP sink needs a target URL from somewhere: either a static `url` WITH option or a per-row `url` VARCHAR column. If neither is present, `validate_http_sink` fails the sink creation because the sink would have nowhere to send HTTP requests.

Source

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

            }
            (Some(url), None) => {
                let url = url
                    .parse()
                    .context("invalid URL")
                    .map_err(SinkError::Config)?;
                HttpUrl::Static(url)
            }
            (None, Some(url_index)) => {
                if fields[url_index].data_type != DataType::Varchar {
                    return Err(SinkError::Config(anyhow!(
                        "HTTP sink url column must be varchar, got {:?}",
                        fields[url_index].data_type
                    )));
                }
                HttpUrl::Dynamic { url_index }
            }
            (None, None) => {
                return Err(SinkError::Config(anyhow!(
                    "HTTP sink requires either url option or url column"
                )));
            }
        };

        (payload_index, url, fields[payload_index].data_type.clone())
    };

    if payload_type != DataType::Varchar && payload_type != DataType::Jsonb {
        return Err(SinkError::Config(anyhow!(
            "HTTP sink payload column must be varchar or jsonb, got {:?}",
            payload_type
        )));
    }

    let mut header_map = HeaderMap::new();
    header_map.insert(
        CONTENT_TYPE,

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Add `url='https://...'` to the sink's WITH clause
  2. Or add/rename a VARCHAR column named `url` in the sink schema for per-row targets
  3. Check WITH-clause spelling: the option key must be exactly `url`

Example fix

// before
CREATE SINK s FROM t WITH (connector='http', format='append_only');
// after
CREATE SINK s FROM t WITH (connector='http', url='https://api.example.com/ingest', format='append_only');
Defensive patterns

Strategy: validation

Validate before calling

let has_url_opt = with_options.contains_key("url");
let has_url_col = fields.iter().any(|f| f.name == "url");
if !has_url_opt && !has_url_col {
    return Err("HTTP sink requires a url option or a VARCHAR url column".into());
}

Prevention

When it happens

Trigger: Creating an HTTP sink with `WITH (connector='http')` (or with connector params but no `url`) while the sink schema has no column named `url` — the `(None, None)` match arm in `validate_http_sink`.

Common situations: Users forget the `url` option entirely when first configuring the HTTP sink; renaming the endpoint column so it's no longer named `url`; typos like `uri` or `endpoint` in the WITH clause.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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