{"record":{"id":"2171ce753c0297cc","repo":"risingwavelabs/risingwave","slug":"clickhouse-error-0","errorCode":null,"errorMessage":"ClickHouse error: {0}","messagePattern":"ClickHouse error: (.+?)","errorType":"exception","errorClass":"SinkError","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/mod.rs","lineNumber":1126,"sourceCode":"    #[error(\"Iceberg error: {0}\")]\n    Iceberg(\n        #[source]\n        #[backtrace]\n        anyhow::Error,\n    ),\n    #[error(\"config error: {0}\")]\n    Config(\n        #[source]\n        #[backtrace]\n        anyhow::Error,\n    ),\n    #[error(\"coordinator error: {0}\")]\n    Coordinator(\n        #[source]\n        #[backtrace]\n        anyhow::Error,\n    ),\n    #[error(\"ClickHouse error: {0}\")]\n    ClickHouse(String),\n    #[error(\"Redis error: {0}\")]\n    Redis(String),\n    #[error(\"Http error: {0}\")]\n    Http(\n        #[source]\n        #[backtrace]\n        anyhow::Error,\n    ),\n    #[error(\"Mqtt error: {0}\")]\n    Mqtt(\n        #[source]\n        #[backtrace]\n        anyhow::Error,\n    ),\n    #[error(\"Nats error: {0}\")]\n    Nats(\n        #[source]","sourceCodeStart":1108,"sourceCodeEnd":1144,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/mod.rs#L1108-L1144","documentation":"`SinkError::ClickHouse` is a plain `String` variant of `SinkError`, thrown when the ClickHouse sink encounters an error reported by the ClickHouse server or client driver. Displayed as \"ClickHouse error: {0}\"; because it stores only a formatted string, the original cause chain is not preserved.","triggerScenarios":"Writing to ClickHouse from the sink: establishing the client connection, executing INSERTs against a table, schema/table-name resolution, authentication failures, or the ClickHouse server rejecting a request with an error code that the sink formats into this variant.","commonSituations":"Wrong host/port, user, or password in `WITH` options; target table or database missing, or engine incompatible with inserts (e.g. non-MergeTree family without allowed settings); column name/type mismatch between RisingWave sink schema and ClickHouse table; server rejects batch due to part limits or quota exceeded.","solutions":["Read the embedded message — ClickHouse server errors name the failing table/column and error code.","Verify connection settings in the sink `WITH` clause: `url`/host, port (native 9000 vs HTTP 8123), user, password, database, table.","Confirm the ClickHouse table exists, is insertable (e.g. MergeTree family), and its columns match the sink schema in name and type.","Check server-side limits (max_parts_in_total, quotas, auth grants for the user's IP) if the message references limits or access denial."],"exampleFix":"-- before\nCREATE SINK s FROM mv WITH (\n  connector = 'clickhouse',\n  clickhouse.url = 'http://localhost:8123',\n  clickhouse.table = 'nonexistent_table'\n);\n-- after\nCREATE SINK s FROM mv WITH (\n  connector = 'clickhouse',\n  clickhouse.url = 'http://localhost:8123',\n  clickhouse.user = 'default',\n  clickhouse.password = '...',\n  clickhouse.database = 'default',\n  clickhouse.table = 'my_table'\n);","handlingStrategy":"try-catch","validationCode":"async fn check_clickhouse_table(opts: &ClickHouseConfig) -> Result<(), String> {\n    let client = clickhouse::Client::default().with_url(&opts.url).with_user(&opts.user).with_password(&opts.password);\n    let exists: Option<u8> = client\n        .query(\"SELECT 1 FROM system.tables WHERE database = ? AND name = ?\")\n        .bind(&opts.database).bind(&opts.table)\n        .fetch_optional().await.map_err(|e| e.to_string())?;\n    anyhow::ensure!(exists.is_some(), \"clickhouse table {}.{} not found\", opts.database, opts.table);\n    Ok(())\n}","typeGuard":"fn as_clickhouse_error(err: &SinkError) -> Option<&str> {\n    if let SinkError::ClickHouse(msg) = err { Some(msg) } else { None }\n}","tryCatchPattern":"match sink.write(batch).await {\n    Err(SinkError::ClickHouse(msg)) => {\n        if msg.contains(\"Code: 252\") || msg.contains(\"too many parts\") {\n            // transient server-side limit: back off and retry\n            tokio::time::sleep(Duration::from_secs(5)).await;\n        } else if msg.contains(\"Authentication\") || msg.contains(\"Unknown table\") {\n            // deterministic: fix connection options or create the table; do not retry\n            log::error!(\"clickhouse config/table error: {msg}\");\n            return Err(SinkError::ClickHouse(msg).into());\n        }\n    }\n    Err(e) => return Err(e.into()),\n    Ok(_) => {}\n}","preventionTips":["Verify host/port (native 9000 vs HTTP 8123), user, and password with a standalone ClickHouse client first.","Create the target table with an insertable engine (MergeTree family) and schema matching the sink before CREATE SINK.","Watch for server limits (max_parts_in_total, quotas) on high-frequency inserts and batch appropriately.","The variant only carries a formatted string — parse the ClickHouse error code from the message for classification."],"tags":["clickhouse","sink","database","risingwave"],"backgroundTag":"database-write-failed","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}