infiniflow/ragflow · error · UnexpectedValidationError

Azure Blob prune listing failed: {exc}

Error message

Azure Blob prune listing failed: {exc}

What it means

Wraps any exception raised while iterating list_blobs() during the prune/permission-sync listing in retrieve_all_slim_docs_perm_sync. Everything from network resets to SDK deserialization errors becomes UnexpectedValidationError with this prefix and the original exception chained.

Source

Thrown at common/data_source/azure_blob_connector.py:259

    ) -> Generator[list[SlimDocument], None, None]:
        """Yield batches of slim documents for prune / permission sync."""
        if self._container_client is None:
            raise ConnectorMissingCredentialError("Azure Blob")

        batch: list[SlimDocument] = []
        try:
            for blob_props in self._container_client.list_blobs(name_starts_with=self.prefix or None):
                name = blob_props.name
                if not _has_supported_extension(name, self.allow_images):
                    continue
                if callback:
                    callback(name, name)
                batch.append(SlimDocument(id=name))
                if len(batch) >= self.batch_size:
                    yield batch
                    batch = []
        except Exception as exc:
            raise UnexpectedValidationError(f"Azure Blob prune listing failed: {exc}") from exc

        if batch:
            yield batch

    # ------------------------------------------------------------------
    # Internal document iteration
    # ------------------------------------------------------------------

    def _iter_documents(
        self,
        checkpoint: AzureBlobCheckpoint | None = None,
        since_epoch: float | None = None,
        until_epoch: float | None = None,
    ):
        from common.data_source.models import Document

        if self._container_client is None:
            raise ConnectorMissingCredentialError("Azure Blob")

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Retry the sync job — listings are idempotent, so a simple re-run is safe
  2. For SAS expiry mid-listing: issue a longer-lived token or switch to account-key auth for bulk prune jobs
  3. Check exc.__cause__ to distinguish network errors from SDK errors; upgrade azure-storage-blob if the cause is a parse error
  4. Reduce batch pressure by lowering batch_size so pagination checkpoints are hit sooner
Defensive patterns

Strategy: retry

Validate before calling

# No local pre-check predicts a mid-listing failure; cap exposure by
# checking credential longevity up front:
if sas_token and sas_expires_within(sas_token, minutes=30):
    raise ValueError("SAS token too short-lived for a full prune listing")

Try / catch

from tenacity import retry, retry_if_exception, stop_after_attempt, wait_exponential
@retry(
    retry=retry_if_exception(lambda e: isinstance(e, UnexpectedValidationError)),
    stop=stop_after_attempt(3),
    wait=wait_exponential(min=2, max=60),
)
def run_perm_sync(connector, creds):
    connector.load_credentials(creds)
    return list(connector.retrieve_all_slim_docs_perm_sync())

Prevention

When it happens

Trigger: Calling retrieve_all_slim_docs_perm_sync and the Azure list_blobs pager throws mid-iteration: transient network failure, SAS token expiring partway through a long listing, or a paged-response deserialization error from an SDK/client version mismatch.

Common situations: Large containers where listing outlives a short-lived SAS token, proxies killing long HTTP responses, or intermittent DNS/connectivity issues in self-hosted deployments.

Related errors


AI-assisted analysis of infiniflow/ragflow@554fb1133a (2026-08-15). Data as JSON: /api/errors/0c9dcbb3a174ee0e. Report an issue: GitHub.