risingwavelabs/risingwave · error · SinkError::Config

HTTP sink url column must be varchar, got {:?}

Error message

HTTP sink url column must be varchar, got {:?}

What it means

When the HTTP sink is configured with a dynamic `url` column (no static `url` option), that column's data type must be VARCHAR since it holds a URL string per row. `validate_http_sink` rejects the sink if the column exists but has any other type.

Source

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

        let url_index = fields
            .iter()
            .position(|field| field.name == HTTP_SINK_URL_COLUMN);
        let url = match (url, url_index) {
            (Some(_), Some(_)) => {
                return Err(SinkError::Config(anyhow!(
                    "HTTP sink url option cannot coexist with url column"
                )));
            }
            (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!(

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Alter the source/table so the `url` column is VARCHAR
  2. Cast the column when defining the sink query: SELECT url::VARCHAR AS url, ...
  3. Remove the non-varchar `url` column and supply a static `url` option instead

Example fix

// before
SELECT url::JSONB AS url, payload FROM t; -- sink schema
// after
SELECT url::VARCHAR AS url, payload FROM t;
Defensive patterns

Strategy: validation

Validate before calling

if let Some(f) = fields.iter().find(|f| f.name == "url") {
    assert!(f.data_type == DataType::Varchar, "url column must be VARCHAR, got {:?}", f.data_type);
}

Type guard

fn is_varchar(f: &Field) -> bool { f.data_type == DataType::Varchar }

Prevention

When it happens

Trigger: Creating an HTTP sink whose schema contains a `url` column typed as something other than VARCHAR (e.g. JSONB, INT, BYTEA); detected in `try_from` -> `validate_http_sink` at the `(None, Some(url_index))` arm.

Common situations: Table column typed as JSONB or struct holding endpoint metadata; users assuming the sink will cast/serialize the column automatically.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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