{"record":{"id":"18db9e8a63a3efda","repo":"infiniflow/ragflow","slug":"azure-blob-container-name-is-required-together-wi-18db9e","errorCode":null,"errorMessage":"Azure Blob: container_name is required together with account_name + account_key","messagePattern":"Azure Blob: container_name is required together with account_name \\+ account_key","errorType":"validation","errorClass":"ConnectorMissingCredentialError","httpStatus":null,"severity":"error","filePath":"common/data_source/azure_blob_connector.py","lineNumber":148,"sourceCode":"                mode = \"connection_string\"\n            elif account_name and account_key:\n                mode = \"account_key\"\n            elif container_url and sas_token:\n                mode = \"sas_token\"\n\n        try:\n            if mode == \"connection_string\":\n                if not conn_str:\n                    raise ConnectorMissingCredentialError(\"Azure Blob: connection_string is required for the connection_string auth mode\")\n                if not container_name:\n                    raise ConnectorMissingCredentialError(\"Azure Blob: container_name is required together with connection_string\")\n                svc = BlobServiceClient.from_connection_string(conn_str)\n                self._container_client = svc.get_container_client(container_name)\n            elif mode == \"account_key\":\n                if not (account_name and account_key):\n                    raise ConnectorMissingCredentialError(\"Azure Blob: account_name and account_key are required for the account_key auth mode\")\n                if not container_name:\n                    raise ConnectorMissingCredentialError(\"Azure Blob: container_name is required together with account_name + account_key\")\n                account_url = f\"https://{account_name}.{_AZURE_ENDPOINT_SUFFIX}\"\n                svc = BlobServiceClient(\n                    account_url=account_url,\n                    credential=account_key,\n                )\n                self._container_client = svc.get_container_client(container_name)\n            elif mode == \"sas_token\":\n                if not (container_url and sas_token):\n                    raise ConnectorMissingCredentialError(\"Azure Blob: container_url and sas_token are required for the sas_token auth mode\")\n                # mirrors RAGFlowAzureSasBlob; strip a leading \"?\" so we\n                # never produce a double-\"?\" that breaks SAS auth.\n                normalized_sas = str(sas_token).lstrip(\"?\")\n                full_url = f\"{container_url}?{normalized_sas}\"\n                self._container_client = ContainerClient.from_container_url(full_url)\n            else:\n                raise ConnectorMissingCredentialError(\n                    \"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.\"\n                )","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/common/data_source/azure_blob_connector.py#L130-L166","documentation":"Raised by RAGFlow's Azure Blob connector when the account_key auth mode is selected but container_name is empty. The connector needs a container to build a ContainerClient from the BlobServiceClient, so it refuses to initialize without one. It is a ConnectorMissingCredentialError, meaning the credential payload itself is incomplete rather than rejected by Azure.","triggerScenarios":"Calling load_credentials (directly or via connector startup) with credentials where auth mode resolves to 'account_key' (account_name + account_key present) but the 'container_name' key is missing, empty, or None. Note the mode check at the top of load_credentials decides the branch before this raise fires.","commonSituations":"Typo in the credential key ('container' vs 'container_name'), UI form that stores container in a separate field never merged into the credential dict, or copy-pasting only the account name/key pair from the Azure portal without the container.","solutions":["Add 'container_name': '<your-container>' to the same credentials dict that holds account_name and account_key","Check for typos/empty-string values in the credential payload (e.g. container_name set to '')","If you intended SAS auth, supply container_url + sas_token instead; if connection-string auth, supply connection_string + container_name"],"exampleFix":"// before\ncreds = {\n  \"account_name\": \"myaccount\",\n  \"account_key\": \"<key>\",\n}\nconnector.load_credentials(creds)\n\n// after\ncreds = {\n  \"account_name\": \"myaccount\",\n  \"account_key\": \"<key>\",\n  \"container_name\": \"my-container\",\n}\nconnector.load_credentials(creds)","handlingStrategy":"validation","validationCode":"def validate_azure_account_key_creds(creds: dict) -> None:\n    mode = creds.get(\"auth_mode\") or _infer_mode(creds)\n    if mode == \"account_key\":\n        missing = [k for k in (\"account_name\", \"account_key\", \"container_name\") if not creds.get(k)]\n        if missing:\n            raise ValueError(f\"account_key mode missing: {missing}\")","typeGuard":"def is_complete_account_key_creds(c: dict) -> bool:\n    return all(\n        isinstance(c.get(k), str) and c[k].strip()\n        for k in (\"account_name\", \"account_key\", \"container_name\")\n    )","tryCatchPattern":"try:\n    connector.load_credentials(creds)\nexcept ConnectorMissingCredentialError as e:\n    # surface to user as a config form error, not a crash\n    raise ConfigError(str(e)) from e","preventionTips":["Validate the credential dict shape (keys present, non-empty strings) before calling load_credentials","Keep a single helper that builds Azure credential dicts so all call sites agree on key names","Add a unit test that asserts load_credentials succeeds for each supported auth-mode fixture"],"tags":["azure","azure-blob","credentials","configuration","connector"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}