Repository navigation
Fix Cosmos backup continuation token failure dropping large containers - #1259
Merged
Paul Lizer (paullizer) merged 1 commit intoAug 18, 2026
Merged
Paul Lizer (paullizer) merged 1 commit into
Paul Lizer (paullizer) merged 1 commit into
Conversation
Data Management backups silently omitted every Cosmos container holding more than one page of documents. Affected containers failed with "BadRequest: Invalid Continuation Token" and were dropped from the backup artifact set while the job still reported completion with warnings, so in most deployments personal conversations and personal messages were never backed up. _iter_backup_cosmos_source_items rebuilt the cross-partition query for each page and replayed the previous pager's continuation token. Cross-partition results are merged client side, so that token cannot resume the merged query, and rebuilding query_items discarded the SDK execution context. Page one always succeeded and page two always failed. Drain a single pager to exhaustion instead, retrying on the same pager so the execution context survives. Also close two observability gaps found while diagnosing this: - Source blob transfer failures produced no log output at all. Log the first failure per resource plus a bounded rollup of distinct failure reasons and counts at resource completion. - Application Insights received the constant [SIMPLE_CHAT_LOG_EVENT] with every string property reduced to a length. Retain sanitized message text and an allowlist of non-sensitive diagnostic keys. Sensitive keys still collapse to a presence flag and secret redaction is unchanged. Fixes #1258
This was referenced Aug 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1258
Problem
Data Management backups silently omitted every Cosmos container holding more than one page of documents. Affected containers were recorded as failed resources and dropped from the backup artifact set entirely, while the job still reported
completed_with_warnings.In practice this meant
personal_conversationsandpersonal_messages— the two largest containers in most deployments — were never backed up. Reproduced on both a full and a partial backup on the same night.The failure boundary matched
DATA_MANAGEMENT_BACKUP_MANIFEST_BATCH_SIZE(100) exactly. Every container that fit in one page succeeded; only the two needing a second page failed.public_documentspersonal_documentsgroup_documentspersonal_conversationspersonal_messagesRoot cause
_iter_backup_cosmos_source_itemsrebuilt the query for every page and replayed the previous pager's continuation token:A cross-partition query is merged client side by the Cosmos SDK. The surfaced continuation token belongs to the underlying per-partition request and cannot resume the merged query, and rebuilding
query_items(...)each iteration discarded the SDK's cross-partition execution context anyway. Page one always succeeded; page two always failed.400is non-retryable, so the resource failed immediately with zero retries.Changes
1. Cosmos source pagination (
functions_data_management.py)The query is built once and a single pager is drained to exhaustion. Retries call
next()on the same pager so the execution context is preserved, and no continuation token is ever passed toby_page(). Page normalization, client-side sorting, cutoff filtering, cancellation checks, and RU/retry telemetry are unchanged. The non-paged fallback used by lightweight test doubles is retained and shares the new page-finalization helper.2. Source blob failure logging (
functions_data_management.py)Per-item blob failures previously produced no log output at all — a run with 19,978 failed blobs left zero trace across a 47 MB console log export containing 72,465
[DEBUG][Log]lines. Now logs the first failure per resource, logs enumeration failures, and emits one rollup at resource completion with counts and distinct reasons. Two helpers keep it bounded:_record_backup_failure_reasoncaps distinct reasons at 10 and aggregates the rest into anOther backup failures.bucket;_summarize_backup_failure_reasonsrenders a frequency-ordered string.3. Application Insights message text (
functions_appinsights.py)Traces arrived as the constant
[SIMPLE_CHAT_LOG_EVENT]with every string property reduced to a length (job_id->sc_job_id_length), making App Insights useless for diagnosis. Now emitssc_messagewith the sanitized message plus the sanitized values of an explicit allowlist of non-sensitive diagnostic keys. Sensitive keys still collapse to a_presentboolean, all other strings still reduce to a length only, andsanitize_log_messageredaction is unchanged.Validation
New regression test
functional_tests/test_data_management_backup_cosmos_pagination.py— the fake pager raises400 Invalid Continuation Tokenif any token is supplied, reproducing the production failure directly.test_multi_page_cosmos_source_drains_a_single_pagerby_pageonly ever receivesNonetest_cutoff_and_unpaged_fallback_still_streamtest_failure_reason_rollup_is_boundedtest_logger_extra_retains_sanitized_diagnosticstest_version_is_at_least_fix_versionconfig.pyversion floorFull Data Management regression suite (
functional_tests/test_data_management_*.py): 147 passed, 1 failed.The single failure —
test_data_management_backup_durability.py::test_backup_recovery_and_admin_progress_are_bounded_and_sanitized— was confirmed pre-existing onorigin/Developmentby stashing these changes and re-running it on the clean base. It is unrelated to this PR.Security notes
sanitize_log_messageand are truncated (1024 chars for properties, 8192 for the message)._sanitize_data_management_backup_textbefore reaching logs.Version
0.250.208->0.250.209Documentation
docs/explanation/fixes/COSMOS_BACKUP_CONTINUATION_TOKEN_FIX.mddocs/explanation/release_notes.md