infiniflow/ragflow · error · ConnectorMissingCredentialError

Azure Blob credential rejected: {msg[:300]}

Error message

Azure Blob credential rejected: {msg[:300]}

What it means

Raised by validate_connector_settings when the real Azure API call get_container_properties() fails with an authentication error. The connector maps Azure's 'AuthenticationFailed' or 'InvalidAuthenticationInfo' error strings to ConnectorMissingCredentialError, truncating the Azure message to 300 chars. This is the first error that proves the credential actually reached Azure and was rejected.

Source

Thrown at common/data_source/azure_blob_connector.py:191

    # ------------------------------------------------------------------
    # Validation
    # ------------------------------------------------------------------

    def validate_connector_settings(self) -> None:
        if self._container_client is None:
            raise ConnectorMissingCredentialError("Azure Blob")

        try:
            # get_container_properties() costs one API call; it returns
            # the ETag and last-modified of the container, proving both
            # the credential and the container name are valid.
            self._container_client.get_container_properties()
        except Exception as exc:
            msg = str(exc)
            code = getattr(getattr(exc, "error_code", None), "value", None) or getattr(exc, "error_code", "")
            if "AuthenticationFailed" in msg or "InvalidAuthenticationInfo" in msg:
                raise ConnectorMissingCredentialError(f"Azure Blob credential rejected: {msg[:300]}") from exc
            if "AuthorizationPermissionMismatch" in msg or "403" in msg:
                raise InsufficientPermissionsError(f"Azure Blob: insufficient permissions on container: {msg[:300]}") from exc
            if "ContainerNotFound" in msg or "404" in msg:
                raise ConnectorValidationError(f"Azure Blob: container not found: {msg[:300]}") from exc
            raise UnexpectedValidationError(f"Azure Blob validation failed ({code}): {msg[:300]}") from exc

    # ------------------------------------------------------------------
    # Checkpoint helpers
    # ------------------------------------------------------------------

    def build_dummy_checkpoint(self) -> AzureBlobCheckpoint:
        return AzureBlobCheckpoint(has_more=True)

    def validate_checkpoint_json(self, checkpoint_json: str) -> AzureBlobCheckpoint:
        try:
            return AzureBlobCheckpoint.model_validate_json(checkpoint_json)
        except Exception:
            return self.build_dummy_checkpoint()

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Regenerate/re-copy the account key or SAS token from the Azure portal and update the stored credential
  2. For SAS: check expiry and start time (skew), and that it is signed for the right account and container with the 'container' resource and 'read'+'list' permissions
  3. For connection string: verify against the portal's Access keys blade — a rotated key2 invalidates old values
  4. Retry validation after updating; if it still fails, decode the Azure error body (first 300 chars are included in the message)
Defensive patterns

Strategy: retry

Validate before calling

# No purely local pre-check can verify an Azure credential; the cheapest
# pre-flight is the same call the connector makes:
from datetime import datetime, timezone
if sas_token:
    se = re.search(r"se=(\d{4}-\d{2}-\d{2}T[\d:%Z-]+)", sas_token)
    if se and datetime.now(timezone.utc) > datetime.fromisoformat(se.group(1).replace("Z", "+00:00")):
        raise ValueError("SAS token already expired")

Try / catch

try:
    connector.validate_connector_settings()
except ConnectorMissingCredentialError as e:
    if "credential rejected" in str(e):
        # credential is definitively bad — refresh it, do not blind-retry
        creds = refresh_from_secret_store()
        connector.load_credentials(creds)
        connector.validate_connector_settings()
    else:
        raise

Prevention

When it happens

Trigger: load_credentials succeeded locally (well-formed key/SAS/connection string) but Azure rejected it during validation: wrong account key (rotated?), expired or wrongly-scoped SAS token, or a connection string whose key no longer matches the storage account.

Common situations: Storage account keys rotated after the credential was stored, SAS token expiry reached, SAS signed against the wrong account/container, or clock skew making SAS start-time in the future.

Related errors


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