infiniflow/ragflow · critical · ConnectorMissingCredentialError

Amazon S3 IAM role ARN is required

Error message

Amazon S3 IAM role ARN is required

What it means

When authentication_method='iam_role', the connector requires a non-empty aws_role_arn to assume; its absence raises ConnectorMissingCredentialError with message 'Amazon S3 IAM role ARN is required'.

Source

Thrown at common/data_source/blob_connector.py:97

    def load_credentials(self, credentials: dict[str, Any]) -> dict[str, Any] | None:
        """Load credentials"""
        logging.debug(f"Loading credentials for {self.bucket_name} of type {self.bucket_type}")

        # Validate credentials
        if self.bucket_type == BlobType.R2:
            if not all(credentials.get(key) for key in ["r2_access_key_id", "r2_secret_access_key", "account_id"]):
                raise ConnectorMissingCredentialError("Cloudflare R2")

        elif self.bucket_type == BlobType.S3:
            authentication_method = credentials.get("authentication_method", "access_key")

            if authentication_method == "access_key":
                if not all(credentials.get(key) for key in ["aws_access_key_id", "aws_secret_access_key"]):
                    raise ConnectorMissingCredentialError("Amazon S3")

            elif authentication_method == "iam_role":
                if not credentials.get("aws_role_arn"):
                    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")

View on GitHub (pinned to 554fb1133a)

Solutions

  1. Set aws_role_arn to the full role ARN, e.g. arn:aws:iam::123456789012:role/MyS3Role
  2. Ensure the runtime identity (instance/task profile) is allowed to sts:AssumeRole that role
  3. Confirm the role's trust policy and S3 permissions

Example fix

// before
creds = {"authentication_method": "iam_role"}

// after
creds = {"authentication_method": "iam_role", "aws_role_arn": "arn:aws:iam::123456789012:role/MyS3Role"}
Defensive patterns

Strategy: validation

Validate before calling

if creds.get("authentication_method") == "iam_role":
    arn = creds.get("aws_role_arn") or ""
    if not arn.startswith("arn:aws:iam::"):
        raise ValueError(f"aws_role_arn missing or malformed: {arn!r}")

Type guard

def is_valid_role_arn(s: str) -> bool:
    """True for strings shaped like arn:aws:iam::<account>:role/<name>."""
    return isinstance(s, str) and s.startswith("arn:aws:iam::") and ":role/" in s and len(s.split(":role/", 1)[1]) > 0

Try / catch

try:
    blob.load_credentials(creds)
except ConnectorMissingCredentialError as e:
    if "IAM role ARN" in str(e):
        creds["aws_role_arn"] = discover_task_role_arn()  # from instance metadata if applicable
        blob.load_credentials(creds)

Prevention

When it happens

Trigger: S3 config selecting iam_role auth but no role ARN supplied (empty/None aws_role_arn).

Common situations: Copying an access-key config and flipping only the method field; role ARN stored under a different key; forgot to create the IAM role.

Related errors


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