risingwavelabs/risingwave · error · SinkError
config deserialization error: {e}
Error message
config deserialization error: {e} What it means
RisingWave's azblob file sink builds an AzblobConfig by converting the user's WITH options BTreeMap into a JSON value and deserializing it with serde_json::from_value. When any option is missing, has an unexpected type, or is not a recognized field, serde fails and the error is wrapped in SinkError::Config with the message "config deserialization error: {e}". It means the CREATE SINK options could not be parsed into the connector's typed config struct.
Source
Thrown at src/connector/src/sink/file_sink/azblob.rs:113
pub struct AzblobSink;
impl UnknownFields for AzblobConfig {
fn unknown_fields(&self) -> HashMap<String, String> {
self.unknown_fields.clone()
}
}
crate::impl_sink_unknown_fields!(AzblobConfig);
impl OpendalSinkBackend for AzblobSink {
type Properties = AzblobConfig;
const SINK_NAME: &'static str = AZBLOB_SINK;
fn from_btreemap(btree_map: BTreeMap<String, String>) -> Result<Self::Properties> {
let config =
serde_json::from_value::<AzblobConfig>(serde_json::to_value(btree_map).unwrap())
.map_err(|e| SinkError::Config(anyhow!(e)))?;
if config.r#type != SINK_TYPE_APPEND_ONLY && config.r#type != SINK_TYPE_UPSERT {
return Err(SinkError::Config(anyhow!(
"`{}` must be {}, or {}",
SINK_TYPE_OPTION,
SINK_TYPE_APPEND_ONLY,
SINK_TYPE_UPSERT
)));
}
Ok(config)
}
fn new_operator(properties: AzblobConfig) -> Result<Operator> {
FileSink::<AzblobSink>::new_azblob_sink(properties)
}
fn get_path(properties: Self::Properties) -> String {
properties.common.path
}View on GitHub (pinned to 6469eb736d)
Solutions
- Check the error's inner serde message: it names the exact missing/unknown/invalid field; fix that WITH option in CREATE SINK.
- Verify required azblob options are present: azblob_container_name, azblob_account_name, azblob_access_key, plus r#type, path, and format options.
- Correct any misspelled or unsupported option names and remove options not defined on AzblobConfig.
- Confirm credentials are plain string values with no characters that break option parsing.
- Consult the azblob sink documentation for the current option list, since fields can change between versions.
Example fix
// before CREATE SINK s FROM mv WITH ( connector = 'azblob', container_name = 'mycontainer', type = 'append-only' ); // after (correct option names + required fields) CREATE SINK s FROM mv WITH ( connector = 'azblob', azblob_container_name = 'mycontainer', azblob_account_name = 'myaccount', azblob_access_key = 'secret-key', r#type = 'append-only', path = 'exports/' );
Defensive patterns
Strategy: validation
Validate before calling
const REQUIRED: [&str; 4] = ["azblob_container_name", "azblob_account_name", "azblob_access_key", "path"];
for k in REQUIRED {
if !opts.contains_key(k) {
return Err(format!("missing azblob sink option: {k}"));
}
}
match opts.get("r#type").map(String::as_str) {
Some("append-only") | Some("upsert") => {}
other => return Err(format!("r#type must be append-only or upsert, got {other:?}")),
} Try / catch
match AzblobSink::from_btreemap(opts) {
Ok(cfg) => proceed(cfg),
Err(SinkError::Config(e)) => eprintln!("fix sink WITH options: {e:#}"),
Err(e) => return Err(e),
} Prevention
- Validate WITH options against the connector schema before running CREATE SINK.
- Keep a canonical example DDL per connector and copy option names from it.
- Match option names exactly to AzblobConfig fields; avoid aliases from other connectors.
- Always set r#type explicitly on every file sink.
- After upgrading RisingWave, re-check sink DDL against the new config fields.
When it happens
Trigger: CREATE SINK with connector='azblob' where a required field (e.g. azblob_container_name, azblob_account_name, azblob_access_key, path, r#type) is absent, or a field is given a wrongly-typed value, or an unknown/misspelled option name is supplied so serde deserialization of BTreeMap -> AzblobConfig fails.
Common situations: Typo in a WITH option key (e.g. 'container' instead of 'azblob_container_name'); forgetting the access key or account name; copying options from another sink connector (s3/gcs) whose field names differ; newer RisingWave versions adding required fields that older create statements lack.
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
- `{}` must be {}, or {}
- config deserialization error: {e}
- config deserialization error: {e}
- sink type unsupported: {}
- sink format unsupported: {}
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/9a51e744fab84bb4.
Report an issue: GitHub.