risingwavelabs/risingwave · error · SinkError::Config
HTTP sink payload column must be varchar or jsonb, got {:?}
Error message
HTTP sink payload column must be varchar or jsonb, got {:?} What it means
The HTTP sink sends the `payload` column as the request body, so it must be a string (VARCHAR) or JSONB that can be serialized. `validate_http_sink` rejects the sink if the payload column has any other type (e.g. INT, struct, bytea).
Source
Thrown at src/connector/src/sink/http.rs:193
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,
content_type
.unwrap_or(match payload_type {
DataType::Varchar => "text/plain",
DataType::Jsonb => "application/json",
_ => unreachable!("validated HTTP sink column type"),
})
.parse()
.context("invalid content_type")
.map_err(SinkError::Config)?,
);View on GitHub (pinned to 6469eb736d)
Solutions
- Cast the payload column in the sink query: SELECT payload::JSONB AS payload ... or payload::VARCHAR
- Change the underlying table column type to VARCHAR or JSONB
- Serialize complex types to JSONB before sinking
Example fix
// before SELECT payload FROM t; -- payload is INT // after SELECT payload::VARCHAR AS payload FROM t; -- or payload::JSONB
Defensive patterns
Strategy: validation
Validate before calling
if let Some(f) = fields.iter().find(|f| f.name == "payload") {
let ok = f.data_type == DataType::Varchar || f.data_type == DataType::Jsonb;
assert!(ok, "payload column must be VARCHAR or JSONB, got {:?}", f.data_type);
} Type guard
fn is_valid_payload(f: &Field) -> bool {
matches!(f.data_type, DataType::Varchar | DataType::Jsonb)
} Prevention
- Store HTTP payloads as VARCHAR or JSONB only
- Cast other types (e.g. ::JSONB for structs) in the sink SELECT
- Watch for ALTER TABLE changes to the payload column type
When it happens
Trigger: Creating an HTTP sink whose `payload` column (located by name at `payload_index`) is typed as anything other than VARCHAR or JSONB — checked in `try_from` -> `validate_http_sink` after URL resolution.
Common situations: Payload column typed as INT/BYTEA/struct in the table; users expecting the sink to stringify arbitrary types; schema drift after ALTER TABLE changes the payload column type.
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
- HTTP sink url column must be varchar, got {:?}
- HTTP sink url option cannot coexist with url column
- HTTP sink requires either url option or url column
- unexpected url column type, expected varchar
- unexpected payload column type, expected varchar or jsonb
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/f4ba23b14b4a945d.
Report an issue: GitHub.