{"record":{"id":"2483ff4c92843c66","repo":"influxdata/influxdb","slug":"v2-catalog-should-exist-since-checkpoint-was-found","errorCode":null,"errorMessage":"v2 catalog should exist since checkpoint was found","messagePattern":"v2 catalog should exist since checkpoint was found","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"influxdb3_catalog/src/catalog/migrations/v3.rs","lineNumber":101,"sourceCode":"\n    if v3_store.load_snapshot().await?.is_some() {\n        return Ok(MigrationResult::AlreadyMigrated);\n    }\n\n    let v2_store = ostore::v2::ObjectStoreCatalog::new(\n        Arc::clone(&prefix),\n        u64::MAX,\n        Arc::clone(&store),\n        StorageMode::default(),\n    );\n\n    if !v2_store.checkpoint_exists().await? {\n        return Ok(MigrationResult::NothingToMigrate);\n    }\n\n    let v2_catalog = ser::v2::load_catalog(Arc::clone(&prefix), &v2_store)\n        .await?\n        .expect(\"v2 catalog should exist since checkpoint was found\");\n\n    let catalog_uuid = v2_catalog.catalog_uuid;\n    let catalog_sequence = v2_catalog.sequence_number();\n    let v2_snapshot = v2_catalog.snapshot();\n    let batch = synthesize_records(&v2_snapshot);\n\n    let mut v3_inner = V3InnerCatalog::new(Arc::clone(&prefix), catalog_uuid);\n    apply_records(\n        batch.as_slice(),\n        &mut v3_inner,\n        catalog_sequence,\n        RestorePreload::empty(),\n    )\n    .map_err(|e| MigrationError::Unexpected(anyhow::anyhow!(e)))?;\n    let v3_snapshot_bytes = v3_inner.create_snapshot();\n\n    if !v2_catalog.has_upgraded {\n        let next_sequence = catalog_sequence.next();","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_catalog/src/catalog/migrations/v3.rs#L83-L119","documentation":"A `.expect(...)` panic inside `check_and_migrate_v2_to_v3`: after confirming a v2 checkpoint exists, the code loads the v2 catalog and asserts it must deserialize successfully. It fires when the persisted v2 catalog bytes are missing/corrupt despite a checkpoint marker being present, i.e. a broken invariant between the checkpoint and the catalog object.","triggerScenarios":"Running the v2->v3 catalog migration when the object store has a v2 checkpoint but `load_catalog` returns None or fails to deserialize — e.g. truncated/partially written catalog object, deleted/overwritten catalog object, or mismatched store prefix.","commonSituations":"Interrupted writes to object storage (network drop mid-PUT), manual tampering/cleanup of catalog objects, restoring a backup that contains the checkpoint but not the catalog, or pointing a new node at a bucket with stale/partial v2 data.","solutions":["Inspect the object store at the v2 prefix and verify the catalog object referenced by the checkpoint exists and is complete.","Restore the missing/corrupt v2 catalog object from backup or re-copy it from a healthy node.","If v2 data is not needed, remove the v2 checkpoint so the migration returns NothingToMigrate instead of panicking.","Re-run migration from a consistent snapshot of the store; report persistent corruption to InfluxData since this is an unrecoverable panic path."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// This is a panic, not a returned error — run migration in a worker and catch_unwind\nlet result = std::panic::catch_unwind(|| check_and_migrate_v2_to_v3(prefix, store));\nif result.is_err() { restore_v2_catalog_from_backup_or_abort(); }","preventionTips":["Take a consistent object-store snapshot/backup before running catalog migrations.","Never manually delete or edit v2 catalog/checkpoint objects.","Ensure object-store writes complete (avoid killing the process mid-migration).","Restore checkpoints and catalog objects together, never partially."],"tags":["influxdb3","catalog-migration","corruption","panic","rust"],"backgroundTag":"internal-invariant-violation","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}