infiniflow/ragflow · error · ConnectorMissingCredentialError

Azure Blob credentials are incomplete. Provide one of: (a) c

Error message

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.

What it means

The catch-all for an unrecognized auth mode in the Azure Blob connector's load_credentials. The if/elif chain covers connection_string, account_key, and sas_token; anything else falls to the else branch and raises this message listing the three valid credential shapes. It is purely local — no network call happens.

Source

Thrown at common/data_source/azure_blob_connector.py:164

                    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
    # ------------------------------------------------------------------

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

        try:

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Supply one of the three documented credential sets: (a) connection_string + container_name, (b) account_name + account_key + container_name, (c) container_url + sas_token
  2. If you set an explicit mode key, correct its value to one of connection_string | account_key | sas_token
  3. Log the credential KEYS (never values) before load_credentials to see which branch the mode resolver picked

Example fix

// before
creds = {"tenant_id": "...", "client_secret": "..."}  // unsupported shape
connector.load_credentials(creds)

// after
creds = {
  "account_name": "myaccount",
  "account_key": "<key>",
  "container_name": "my-container",
}
connector.load_credentials(creds)
Defensive patterns

Strategy: validation

Validate before calling

AZURE_MODES = {"connection_string", "account_key", "sas_token"}
def validate_azure_mode(creds: dict) -> None:
    mode = creds.get("auth_mode")
    if mode is not None and mode not in AZURE_MODES:
        raise ValueError(f"unsupported auth_mode {mode!r}; expected one of {sorted(AZURE_MODES)}")

Type guard

def has_any_supported_azure_shape(c: dict) -> bool:
    return bool(c.get("connection_string")) or is_complete_account_key_creds(c) or is_complete_sas_creds(c)

Try / catch

try:
    connector.load_credentials(creds)
except ConnectorMissingCredentialError as e:
    # the message enumerates the three valid shapes; echo it verbatim to the user
    raise ConfigError(str(e)) from e

Prevention

When it happens

Trigger: The mode variable computed from the credentials dict matches none of 'connection_string', 'account_key', 'sas_token' — e.g. an explicit 'auth_mode' key with a typo ('sas'), or a credential set that has none of the identifying key combinations so mode ends up as some sentinel/empty value.

Common situations: A stale config from an older connector version that used a different auth_mode naming, hand-edited YAML/JSON with 'mode: service_principal', or a completely empty credentials dict passed to load_credentials.

Related errors


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