{"record":{"id":"51916cd290ec97a7","repo":"quickwit-oss/quickwit","slug":"window-duration-secs-mismatch-in-expected","errorCode":null,"errorMessage":"window_duration_secs mismatch in {}: expected {}, found {}","messagePattern":"window_duration_secs mismatch in (.+?): expected (.+?), found (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-parquet-engine/src/merge/mod.rs","lineNumber":430,"sourceCode":"                    );\n                }\n            }\n            None => {\n                consensus_window_start = Some(file_window_start);\n            }\n        }\n\n        // Window duration: must be consistent.\n        let file_window_duration = find_kv(PARQUET_META_WINDOW_DURATION)\n            .map(|s| s.parse::<u32>())\n            .transpose()\n            .with_context(|| format!(\"parsing window_duration from {}\", path.display()))?\n            .unwrap_or(0);\n\n        match &consensus_window_duration {\n            Some(expected) => {\n                if file_window_duration != *expected {\n                    bail!(\n                        \"window_duration_secs mismatch in {}: expected {}, found {}\",\n                        path.display(),\n                        expected,\n                        file_window_duration\n                    );\n                }\n            }\n            None => {\n                consensus_window_duration = Some(file_window_duration);\n            }\n        }\n\n        // Merge ops: take the max across all inputs.\n        let file_merge_ops = find_kv(PARQUET_META_NUM_MERGE_OPS)\n            .map(|s| s.parse::<u32>())\n            .transpose()\n            .with_context(|| format!(\"parsing num_merge_ops from {}\", path.display()))?\n            .unwrap_or(0);","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-parquet-engine/src/merge/mod.rs#L412-L448","documentation":"Same consensus check as window_start but for the `window_duration_secs` parquet metadata key. All inputs to a merge must declare the same window duration (missing treated as 0); a differing value aborts the merge because merged output could not carry a coherent window duration.","triggerScenarios":"Calling merge_sorted_parquet_files_impl with input files whose `window_duration_secs` KV metadata differs (including one file missing the key, which defaults to 0).","commonSituations":"Mixing splits written before windowing metadata was introduced (missing key => 0) with newer splits that carry a real duration; misconfigured windowing on one indexing node in the cluster.","solutions":["Verify all inputs share the same `window_duration_secs` metadata; exclude divergent files from the merge group.","Re-index legacy splits lacking the key so they carry the correct duration.","Fix cluster config so all indexers use the same window duration.","Update the merge planner to partition split candidates by window duration."],"exampleFix":"// before: legacy split without duration merged with new splits\nmerge(vec![legacy_split, new_split])?;\n// after: filter by consistent window_duration_secs first\nlet expected = splits[0].window_duration_secs;\nlet compatible: Vec<_> = splits.into_iter().filter(|s| s.window_duration_secs == expected).collect();\nmerge(compatible)?;","handlingStrategy":"validation","validationCode":"fn durations_consistent(files: &[PathBuf]) -> anyhow::Result<()> {\n    let mut vals: HashSet<u64> = HashSet::new();\n    for f in files { vals.insert(read_parquet_kv(f, \"window_duration_secs\").unwrap_or(0)); }\n    anyhow::ensure!(vals.len() <= 1, \"mixed window_duration_secs across merge inputs\");\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match merge(...).await {\n    Err(e) if e.to_string().contains(\"window_duration_secs mismatch\") => {\n        // quarantine legacy split, re-index, then retry merge\n    }\n    other => other?,\n}","preventionTips":["Re-index pre-windowing splits so the key is always present.","Keep windowing config identical on all indexer nodes.","Include window_duration_secs in merge-group keys."],"tags":["merge","parquet","metadata-validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}