{"record":{"id":"f5efb1c6d450179e","repo":"risingwavelabs/risingwave","slug":"fill-secrets-for-iceberg","errorCode":null,"errorMessage":"fill secrets for iceberg","messagePattern":"fill secrets for iceberg","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/meta/src/manager/iceberg_pk_index_sink/mod.rs","lineNumber":58,"sourceCode":"        .get(UPSTREAM_SOURCE_KEY)\n        .map(|v| v.eq_ignore_ascii_case(\"iceberg\"))\n        .unwrap_or(false);\n    let pk_index_enabled = properties\n        .get(ENABLE_PK_INDEX)\n        .map(|v| v.eq_ignore_ascii_case(\"true\"))\n        .unwrap_or(false);\n    connector_match && pk_index_enabled\n}\n\n/// Build an [`IcebergConfig`] from a [`PbSink`], filling secret refs along the\n/// way. Used at CREATE SINK time and during recovery to (re-)register the\n/// commit coordinator.\npub fn build_iceberg_config(pb_sink: &PbSink) -> anyhow::Result<IcebergConfig> {\n    let properties: BTreeMap<String, String> = pb_sink.properties.clone().into_iter().collect();\n    let secret_refs: BTreeMap<_, _> = pb_sink.secret_refs.clone().into_iter().collect();\n    let with_secrets = LocalSecretManager::global()\n        .fill_secrets(properties, secret_refs)\n        .map_err(|e| anyhow!(e).context(\"fill secrets for iceberg\"))?;\n    IcebergConfig::from_btreemap(with_secrets)\n        .map_err(|e| anyhow!(e).context(\"parse iceberg config\"))\n}\n","sourceCodeStart":40,"sourceCodeEnd":62,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/meta/src/manager/iceberg_pk_index_sink/mod.rs#L40-L62","documentation":"build_iceberg_config resolves the sink's secret references through LocalSecretManager::fill_secrets before constructing the Iceberg catalog config. If a referenced secret cannot be read (missing from the store, bad ref id), the error is wrapped with this context so the caller knows secret resolution — not parsing — failed while building the coordinator's IcebergConfig.","triggerScenarios":"Coordinator creation from a PbSink whose secret_refs entry cannot be filled — the referenced secret id does not exist or is unreadable on this meta node (secret dropped, not synced, or wrong ref in the sink definition).","commonSituations":"Secret deleted while the sink still references it; wrong secret ref name given at CREATE SINK; meta node missing synced secret state after restore/recovery.","solutions":["List the sink's secret_refs and confirm each referenced secret exists; recreate missing secrets with the same refs.","Recreate the sink (DROP SINK + CREATE SINK) so secret refs are re-registered and synced.","Check secret-manager logs for the exact ref id that failed and fix the ref name/id in the sink definition.","If it is a sync issue after recovery, restart the meta node so it reloads secret state."],"exampleFix":"-- before: sink references a dropped secret\nCREATE SINK s FROM mv WITH (connector='iceberg', secret=iceberg_secret_ref);\n-- after: recreate the secret first, then the sink\nCREATE SECRET iceberg_secret WITH (backend='meta', properties={'access_key':'...','secret_key':'...'});\nCREATE SINK s FROM mv WITH (connector='iceberg', secret=iceberg_secret_ref);","handlingStrategy":"validation","validationCode":"// before building the coordinator, ensure all refs resolve\nfor ref_id in sink.secret_refs.keys() {\n    if LocalSecretManager::global().read_secret(ref_id).is_none() {\n        return Err(anyhow!(\"secret {} referenced by sink is missing\", ref_id));\n    }\n}","typeGuard":null,"tryCatchPattern":"let cfg = match build_iceberg_config(&sink) {\n    Ok(cfg) => cfg,\n    Err(e) if e.to_string().contains(\"fill secrets for iceberg\") => {\n        // recreate the missing secret then retry\n        recreate_secrets(&sink).await?;\n        build_iceberg_config(&sink)?\n    }\n    Err(e) => return Err(e),\n};","preventionTips":["Create secrets before the sink that references them.","Never drop a secret while a sink still references it.","Verify secret sync state on meta nodes after recovery."],"tags":["secrets","iceberg","configuration"],"backgroundTag":"missing-credentials","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}