infiniflow/ragflow · error · ConnectorMissingCredentialError

Failed to initialise Azure Blob client: {exc}

Error message

Failed to initialise Azure Blob client: {exc}

What it means

Wraps any unexpected exception thrown while constructing the Azure SDK client objects in load_credentials (BlobServiceClient.from_connection_string, BlobServiceClient(...), or ContainerClient.from_container_url). The original exception is chained via 'from exc', so the full cause is preserved. ConnectorMissingCredentialError is used even though the root cause is usually a malformed credential value rather than a missing one.

Source

Thrown at common/data_source/azure_blob_connector.py:170

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

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Inspect the chained exception (exc.__cause__) — it carries the exact SDK error
  2. Validate the connection string format (must contain AccountName= and AccountKey= pairs) or re-copy the value from the Azure portal
  3. Trim whitespace/newlines from all credential values before passing them in
  4. Pin/upgrade azure-storage-blob to the connector's tested version

Example fix

# before
creds = {"connection_string": conn_str_from_env_with_trailing_newline, ...}

# after
creds = {
  "connection_string": conn_str_from_env.strip(),
  "container_name": "my-container",
}
connector.load_credentials(creds)
Defensive patterns

Strategy: try-catch

Validate before calling

def clean_azure_creds(creds: dict) -> dict:
    out = {k: v.strip() if isinstance(v, str) else v for k, v in creds.items()}
    if "connection_string" in out and "AccountName=" not in out["connection_string"]:
        raise ValueError("connection_string does not look like an Azure connection string")
    return out

Try / catch

try:
    connector.load_credentials(creds)
except ConnectorMissingCredentialError as e:
    cause = e.__cause__
    logger.error("azure client init failed: %s", cause)
    # distinguish wrap (523) from explicit raises by checking __cause__ presence
    if cause is None:
        raise ConfigError(str(e)) from e
    raise TransientOrFormatError(str(cause)) from e

Prevention

When it happens

Trigger: A credential value is present but malformed such that the azure SDK constructor throws: an unparseable connection string, an account_name containing illegal URL characters producing a bad account_url, or a SAS token/URL combination that from_container_url cannot parse. Deliberately raised ConnectorMissingCredentialErrors are re-raised untouched by the 'except ConnectorMissingCredentialError: raise' guard.

Common situations: Truncated connection string from a secrets manager, a connection string copied with smart quotes or a trailing newline, an account key with whitespace, or a version mismatch in azure-storage-blob changing constructor strictness.

Related errors


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