{"record":{"id":"87a02527099b8795","repo":"infiniflow/ragflow","slug":"unsupported-s3-authentication-method","errorCode":null,"errorMessage":"Unsupported S3 authentication method","messagePattern":"Unsupported S3 authentication method","errorType":"validation","errorClass":"ConnectorMissingCredentialError","httpStatus":null,"severity":"error","filePath":"common/data_source/blob_connector.py","lineNumber":103,"sourceCode":"            if not all(credentials.get(key) for key in [\"r2_access_key_id\", \"r2_secret_access_key\", \"account_id\"]):\n                raise ConnectorMissingCredentialError(\"Cloudflare R2\")\n\n        elif self.bucket_type == BlobType.S3:\n            authentication_method = credentials.get(\"authentication_method\", \"access_key\")\n\n            if authentication_method == \"access_key\":\n                if not all(credentials.get(key) for key in [\"aws_access_key_id\", \"aws_secret_access_key\"]):\n                    raise ConnectorMissingCredentialError(\"Amazon S3\")\n\n            elif authentication_method == \"iam_role\":\n                if not credentials.get(\"aws_role_arn\"):\n                    raise ConnectorMissingCredentialError(\"Amazon S3 IAM role ARN is required\")\n\n            elif authentication_method == \"assume_role\":\n                pass\n\n            else:\n                raise ConnectorMissingCredentialError(\"Unsupported S3 authentication method\")\n\n        elif self.bucket_type == BlobType.GOOGLE_CLOUD_STORAGE:\n            if not all(credentials.get(key) for key in [\"access_key_id\", \"secret_access_key\"]):\n                raise ConnectorMissingCredentialError(\"Google Cloud Storage\")\n\n        elif self.bucket_type == BlobType.OCI_STORAGE:\n            if not all(credentials.get(key) for key in [\"namespace\", \"region\", \"access_key_id\", \"secret_access_key\"]):\n                raise ConnectorMissingCredentialError(\"Oracle Cloud Infrastructure\")\n\n        elif self.bucket_type == BlobType.S3_COMPATIBLE:\n            if not all(credentials.get(key) for key in [\"endpoint_url\", \"aws_access_key_id\", \"aws_secret_access_key\", \"addressing_style\"]):\n                raise ConnectorMissingCredentialError(\"S3 Compatible Storage\")\n\n        else:\n            raise ValueError(f\"Unsupported bucket type: {self.bucket_type}\")\n\n        # Create S3 client\n        self.s3_client = create_s3_client(self.bucket_type, credentials, self.european_residency)","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/common/data_source/blob_connector.py#L85-L121","documentation":"The S3 auth dispatcher accepts only 'access_key', 'iam_role', and 'assume_role'; any other value for authentication_method raises ConnectorMissingCredentialError('Unsupported S3 authentication method').","triggerScenarios":"authentication_method set to something like 'iam', 'role', 'keys', 'session', or an unset-with-typo value (note: a missing key defaults to 'access_key', so this only fires on a present-but-unknown value).","commonSituations":"Config authored from memory with a plausible-but-wrong method name; enum values changing across connector versions; frontend sending display labels instead of machine values.","solutions":["Set authentication_method to exactly one of: access_key, iam_role, assume_role","Add an allowlist check in config-building code so invalid values fail loudly before connector construction"],"exampleFix":"// before\ncreds = {\"authentication_method\": \"iam\", \"aws_role_arn\": \"arn:...\"}\n\n// after\ncreds = {\"authentication_method\": \"iam_role\", \"aws_role_arn\": \"arn:...\"}","handlingStrategy":"validation","validationCode":"ALLOWED = {\"access_key\", \"iam_role\", \"assume_role\"}\nmethod = creds.get(\"authentication_method\", \"access_key\")\nif method not in ALLOWED:\n    raise ValueError(f\"authentication_method must be one of {sorted(ALLOWED)}, got {method!r}\")","typeGuard":"def is_supported_s3_auth_method(m) -> bool:\n    \"\"\"True when m is one of the connector's supported S3 auth methods.\"\"\"\n    return m in {\"access_key\", \"iam_role\", \"assume_role\"}","tryCatchPattern":"try:\n    blob.load_credentials(creds)\nexcept ConnectorMissingCredentialError as e:\n    if \"Unsupported S3 authentication method\" in str(e):\n        creds[\"authentication_method\"] = \"access_key\"  # or iam_role as intended\n        blob.load_credentials(creds)","preventionTips":["Use a dropdown with the three machine values in config UIs, never free text","Normalize incoming config (trim/lowercase) before it reaches load_credentials","Add a unit test pinning the exact set of accepted method strings"],"tags":["amazon-s3","configuration","enum","validation"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}