{"record":{"id":"369f50be6e0e31b9","repo":"risingwavelabs/risingwave","slug":"invalid-backfill-split-pk-column-index-out-of","errorCode":null,"errorMessage":"invalid backfill_split_pk_column_index {}, out of bound","messagePattern":"invalid backfill_split_pk_column_index (.+?), out of bound","errorType":"validation","errorClass":"ConnectorError","httpStatus":null,"severity":"error","filePath":"src/connector/src/source/cdc/external/postgres.rs","lineNumber":196,"sourceCode":"        start_pk: Option<OwnedRow>,\n        primary_keys: Vec<String>,\n        limit: u32,\n    ) -> BoxStream<'_, ConnectorResult<OwnedRow>> {\n        assert_eq!(table_name, self.schema_table_name);\n        self.snapshot_read_inner(table_name, start_pk, primary_keys, limit)\n    }\n\n    #[try_stream(boxed, ok = CdcTableSnapshotSplit, error = ConnectorError)]\n    async fn get_parallel_cdc_splits(&self, options: CdcTableSnapshotSplitOption) {\n        let backfill_num_rows_per_split = options.backfill_num_rows_per_split;\n        if backfill_num_rows_per_split == 0 {\n            return Err(anyhow::anyhow!(\n                \"invalid backfill_num_rows_per_split, must be greater than 0\"\n            )\n            .into());\n        }\n        if options.backfill_split_pk_column_index as usize >= self.pk_indices.len() {\n            return Err(anyhow::anyhow!(format!(\n                \"invalid backfill_split_pk_column_index {}, out of bound\",\n                options.backfill_split_pk_column_index\n            ))\n            .into());\n        }\n        let split_column = self.split_column(&options);\n        let row_stream = if options.backfill_as_even_splits\n            && is_supported_even_split_data_type(&split_column.data_type)\n        {\n            // For certain types, use evenly-sized partition to optimize performance.\n            tracing::info!(?self.schema_table_name, ?self.rw_schema, ?self.pk_indices, ?split_column, \"Get parallel cdc table snapshot even splits.\");\n            self.as_even_splits(options)\n        } else {\n            tracing::info!(?self.schema_table_name, ?self.rw_schema, ?self.pk_indices, ?split_column, \"Get parallel cdc table snapshot uneven splits.\");\n            self.as_uneven_splits(options)\n        };\n        pin_mut!(row_stream);\n        #[for_await]","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/source/cdc/external/postgres.rs#L178-L214","documentation":"The PostgreSQL CDC splitter also validates `backfill_split_pk_column_index` against the table's primary key indices. If the index is >= the number of PK columns, it cannot designate a split column, so this error is thrown. It is an out-of-bounds validation on the split options.","triggerScenarios":"Calling `get_parallel_cdc_splits` with `options.backfill_split_pk_column_index` greater than or equal to `self.pk_indices.len()` — e.g. index 1 supplied for a single-column PK.","commonSituations":"Hand-editing CDC properties with a PK column index that doesn't match the table's actual PK; upstream PK reduced to fewer columns after the source was configured; off-by-one assumptions (1-based vs 0-based index).","solutions":["Set `backfill_split_pk_column_index` to 0 (the first PK column) unless you know the PK layout.","Confirm the upstream table's PK column count and use an index within range (0-based).","Drop and re-create the CDC source so split options and PK metadata are consistent.","Remove the option so the connector picks the default split column."],"exampleFix":"// before: single-column PK but index 1 configured\nWITH (connector = 'postgres-cdc', backfill_split_pk_column_index = '1');\n// after\nWITH (connector = 'postgres-cdc', backfill_split_pk_column_index = '0');","handlingStrategy":"validation","validationCode":"// Check index against the actual PK column count\nlet pk_count = pk_indices.len() as i32;\nif opts.backfill_split_pk_column_index >= pk_count || opts.backfill_split_pk_column_index < 0 {\n    return Err(\"backfill_split_pk_column_index out of bounds\");\n}","typeGuard":null,"tryCatchPattern":"match get_parallel_cdc_splits(opts).await {\n    Err(e) if e.to_string().contains(\"out of bound\") => {\n        // reset the index to 0 and retry\n    },\n    r => r?,\n}","preventionTips":["Omit the option unless you specifically need a non-first PK split column.","Remember indices are 0-based.","Re-validate split options after upstream PK changes."],"tags":["cdc","postgres","index-out-of-bounds","configuration"],"backgroundTag":"index-out-of-bounds","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"}