infiniflow/ragflow · error · ConnectorMissingCredentialError

S3 Compatible Storage

Error message

S3 Compatible Storage

What it means

Raised by BlobStorageConnector.load_credentials when bucket_type is 's3_compatible' and the credentials dict is missing any of: endpoint_url, aws_access_key_id, aws_secret_access_key, addressing_style. S3-compatible providers (MinIO, Ceph, Wasabi, DigitalOcean Spaces, etc.) need an explicit endpoint and addressing style ('path' or 'virtual') in addition to the HMAC key pair, because boto3 cannot guess the endpoint from the key alone.

Source

Thrown at common/data_source/blob_connector.py:115

                    raise ConnectorMissingCredentialError("Amazon S3 IAM role ARN is required")

            elif authentication_method == "assume_role":
                pass

            else:
                raise ConnectorMissingCredentialError("Unsupported S3 authentication method")

        elif self.bucket_type == BlobType.GOOGLE_CLOUD_STORAGE:
            if not all(credentials.get(key) for key in ["access_key_id", "secret_access_key"]):
                raise ConnectorMissingCredentialError("Google Cloud Storage")

        elif self.bucket_type == BlobType.OCI_STORAGE:
            if not all(credentials.get(key) for key in ["namespace", "region", "access_key_id", "secret_access_key"]):
                raise ConnectorMissingCredentialError("Oracle Cloud Infrastructure")

        elif self.bucket_type == BlobType.S3_COMPATIBLE:
            if not all(credentials.get(key) for key in ["endpoint_url", "aws_access_key_id", "aws_secret_access_key", "addressing_style"]):
                raise ConnectorMissingCredentialError("S3 Compatible Storage")

        else:
            raise ValueError(f"Unsupported bucket type: {self.bucket_type}")

        # Create S3 client
        self.s3_client = create_s3_client(self.bucket_type, credentials, self.european_residency)

        # Detect bucket region (only important for S3)
        if self.bucket_type == BlobType.S3:
            self.bucket_region = detect_bucket_region(self.s3_client, self.bucket_name)

        return None

    def _build_document_from_obj(
        self,
        obj: dict[str, Any],
        filename_counts: dict[str, int],
    ) -> Optional[Document]:

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Add endpoint_url (e.g. 'https://minio.example.com:9000') and addressing_style ('path' or 'virtual') to the credentials dict
  2. Confirm aws_access_key_id and aws_secret_access_key are the provider's S3-compatible keys, not IAM role config
  3. Use addressing_style='path' for MinIO/Ceph/local deployments; 'virtual' only if the provider requires virtual-hosted buckets
  4. Include the scheme (http/https) in endpoint_url since it is passed straight into the boto3 endpoint_url parameter

Example fix

// before
connector.load_credentials({
    'aws_access_key_id': key,
    'aws_secret_access_key': secret,
})
// after
connector.load_credentials({
    'endpoint_url': 'https://minio.example.com:9000',
    'aws_access_key_id': key,
    'aws_secret_access_key': secret,
    'addressing_style': 'path',
})
Defensive patterns

Strategy: validation

Validate before calling

REQUIRED_S3C = ['endpoint_url', 'aws_access_key_id', 'aws_secret_access_key', 'addressing_style']
if not all(credentials.get(k) for k in REQUIRED_S3C):
    raise ValueError('s3_compatible needs endpoint_url, key pair, and addressing_style')
if credentials['addressing_style'] not in ('path', 'virtual'):
    raise ValueError("addressing_style must be 'path' or 'virtual'")
connector.load_credentials(credentials)

Type guard

def has_s3_compatible_credentials(c: dict) -> bool:
    return (isinstance(c.get('endpoint_url'), str)
            and c['endpoint_url'].startswith(('http://', 'https://'))
            and bool(c.get('aws_access_key_id'))
            and bool(c.get('aws_secret_access_key'))
            and c.get('addressing_style') in ('path', 'virtual'))

Try / catch

try:
    connector.load_credentials(creds)
except ConnectorMissingCredentialError as e:
    if 'S3 Compatible' in str(e):
        raise ConfigError('endpoint_url + aws key pair + addressing_style required') from e
    raise

Prevention

When it happens

Trigger: Calling load_credentials with bucket_type='s3_compatible' and a credentials dict that has AWS-style keys but no endpoint_url or addressing_style. Also triggered when endpoint_url is '' or None, or when addressing_style is omitted so the client cannot decide between path-style and virtual-host-style URLs.

Common situations: Pointing the connector at a self-hosted MinIO or a third-party S3 clone and reusing the plain S3 credential shape; setting endpoint_url without the scheme; forgetting addressing_style ('path' is required by MinIO and most on-prem deployments, while 'virtual' is needed by some providers).

Related errors


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