infiniflow/ragflow · error · ConnectorMissingCredentialError

Azure Blob: container_url and sas_token are required for the

Error message

Azure Blob: container_url and sas_token are required for the sas_token auth mode

What it means

Raised when the Azure Blob connector is configured for sas_token auth mode but either container_url or sas_token is missing from the credentials. The SAS flow constructs a full URL as f"{container_url}?{normalized_sas}" and hands it to ContainerClient.from_container_url, so both halves are mandatory. It is a local validation failure — no Azure request is made.

Source

Thrown at common/data_source/azure_blob_connector.py:157

                    raise ConnectorMissingCredentialError("Azure Blob: connection_string is required for the connection_string auth mode")
                if not container_name:
                    raise ConnectorMissingCredentialError("Azure Blob: container_name is required together with connection_string")
                svc = BlobServiceClient.from_connection_string(conn_str)
                self._container_client = svc.get_container_client(container_name)
            elif mode == "account_key":
                if not (account_name and account_key):
                    raise ConnectorMissingCredentialError("Azure Blob: account_name and account_key are required for the account_key auth mode")
                if not container_name:
                    raise ConnectorMissingCredentialError("Azure Blob: container_name is required together with account_name + account_key")
                account_url = f"https://{account_name}.{_AZURE_ENDPOINT_SUFFIX}"
                svc = BlobServiceClient(
                    account_url=account_url,
                    credential=account_key,
                )
                self._container_client = svc.get_container_client(container_name)
            elif mode == "sas_token":
                if not (container_url and sas_token):
                    raise ConnectorMissingCredentialError("Azure Blob: container_url and sas_token are required for the sas_token auth mode")
                # mirrors RAGFlowAzureSasBlob; strip a leading "?" so we
                # never produce a double-"?" that breaks SAS auth.
                normalized_sas = str(sas_token).lstrip("?")
                full_url = f"{container_url}?{normalized_sas}"
                self._container_client = ContainerClient.from_container_url(full_url)
            else:
                raise ConnectorMissingCredentialError(
                    "Azure Blob credentials are incomplete. Provide one of: (a) connection_string + container_name, (b) account_name + account_key + container_name, (c) container_url + sas_token."
                )
        except ConnectorMissingCredentialError:
            raise
        except Exception as exc:
            raise ConnectorMissingCredentialError(f"Failed to initialise Azure Blob client: {exc}") from exc

        return None

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

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Set both 'container_url' (e.g. https://account.blob.core.windows.net/container) and 'sas_token' in the credentials dict
  2. If you pasted a URL that already contains the '?sig=...' query, split it: base URL into container_url, query part into sas_token (a leading '?' is stripped automatically)
  3. If you meant key-based auth, supply account_name + account_key + container_name instead

Example fix

// before
creds = {"sas_token": "sv=2022-11-02&sig=..."}
connector.load_credentials(creds)

// after
creds = {
  "container_url": "https://myaccount.blob.core.windows.net/my-container",
  "sas_token": "sv=2022-11-02&sig=...",
}
connector.load_credentials(creds)
Defensive patterns

Strategy: validation

Validate before calling

def validate_azure_sas_creds(creds: dict) -> None:
    url = creds.get("container_url") or ""
    token = creds.get("sas_token") or ""
    if not (url.startswith("https://") and token):
        raise ValueError("sas_token mode requires container_url and sas_token")
    if "sig=" in url:
        raise ValueError("container_url already contains a SAS query; split it")

Type guard

def is_complete_sas_creds(c: dict) -> bool:
    return bool(c.get("container_url", "").startswith("https://") and c.get("sas_token"))

Try / catch

try:
    connector.load_credentials(creds)
except ConnectorMissingCredentialError as e:
    raise ConfigError(str(e)) from e

Prevention

When it happens

Trigger: load_credentials receives credentials containing a sas_token or container_url key that implies the sas_token branch (per the mode resolution logic earlier in load_credentials), while the other of the pair is absent, empty, or None.

Common situations: Copying only the SAS token from Azure Storage Explorer and forgetting the container URL, pasting the full URL (token included) into container_url only, or a secrets manager that stores the two values under different paths and only one was wired into the connector config.

Related errors


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