{"record":{"id":"fdb36f45efd77d9c","repo":"infiniflow/ragflow","slug":"unexpected-s3-client-error-code-error-code-sta","errorCode":null,"errorMessage":"Unexpected S3 client error (code={error_code}, status={status_code}): {e}","messagePattern":"Unexpected S3 client error \\(code=(.+?), status=(.+?)\\): (.+?)","errorType":"validation","errorClass":"ConnectorValidationError","httpStatus":null,"severity":"error","filePath":"common/data_source/blob_connector.py","lineNumber":342,"sourceCode":"            status_code = getattr(e, \"response\", {}).get(\"ResponseMetadata\", {}).get(\"HTTPStatusCode\")\n\n            # Common S3 error scenarios\n            if error_code in [\n                \"AccessDenied\",\n                \"InvalidAccessKeyId\",\n                \"SignatureDoesNotMatch\",\n            ]:\n                if status_code == 403 or error_code == \"AccessDenied\":\n                    raise InsufficientPermissionsError(f\"Insufficient permissions to list objects in bucket '{self.bucket_name}'. Please check your bucket policy and/or IAM policy.\")\n                if status_code == 401 or error_code == \"SignatureDoesNotMatch\":\n                    raise CredentialExpiredError(\"Provided blob storage credentials appear invalid or expired.\")\n\n                raise CredentialExpiredError(f\"Credential issue encountered ({error_code}).\")\n\n            if error_code == \"NoSuchBucket\" or status_code == 404:\n                raise ConnectorValidationError(f\"Bucket '{self.bucket_name}' does not exist or cannot be found.\")\n\n            raise ConnectorValidationError(f\"Unexpected S3 client error (code={error_code}, status={status_code}): {e}\")\n\n\nif __name__ == \"__main__\":\n    # Example usage\n    credentials_dict = {\n        \"aws_access_key_id\": os.environ.get(\"AWS_ACCESS_KEY_ID\"),\n        \"aws_secret_access_key\": os.environ.get(\"AWS_SECRET_ACCESS_KEY\"),\n    }\n\n    # Initialize connector\n    connector = BlobStorageConnector(\n        bucket_type=os.environ.get(\"BUCKET_TYPE\") or \"s3\",\n        bucket_name=os.environ.get(\"BUCKET_NAME\") or \"yyboombucket\",\n        prefix=\"\",\n    )\n\n    try:\n        connector.load_credentials(credentials_dict)","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/common/data_source/blob_connector.py#L324-L360","documentation":"The catch-all ConnectorValidationError raised by BlobStorageConnector.validate_connector_settings when the list_objects_v2 probe fails in a way that matches none of the mapped cases (credential errors, permission errors, missing bucket). It embeds the S3 error code, HTTP status, and the original exception text so the real cause stays diagnosable.","triggerScenarios":"Network-level failures during the probe: DNS resolution errors, TLS certificate failures, connection timeouts, 5xx responses from S3 or the S3-compatible endpoint, throttling (SlowDown/503), VPC endpoint restrictions, or a misconfigured endpoint_url returning an HTML error page that boto3 surfaces oddly.","commonSituations":"Self-hosted MinIO down or restarting; endpoint_url scheme wrong (https against an http-only server); corporate proxy blocking the endpoint; S3 503 SlowDown under heavy listing; clock-skew-induced 403s that fall outside the mapped branches.","solutions":["Read the embedded code/status and exception text — this branch is intentionally transparent; the fix depends on the underlying error","Test reachability of endpoint_url with curl -v (or the provider CLI) from the same host/network","For SlowDown/503, retry after a backoff — validation is a single MaxKeys=1 list, so sustained 503 means throttling or outage","Fix endpoint scheme/TLS config for S3-compatible stores (http vs https mismatch shows up here)"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import socket, urllib.parse\nhost = urllib.parse.urlparse(endpoint_url or 'https://s3.amazonaws.com').hostname\nsocket.getaddrinfo(host, 443)  # DNS check before running validation","typeGuard":null,"tryCatchPattern":"from common.data_source.exceptions import ConnectorValidationError\nfor attempt in range(3):\n    try:\n        connector.validate_connector_settings()\n        break\n    except ConnectorValidationError as e:\n        if 'SlowDown' in str(e) or '503' in str(e) or 'timeout' in str(e).lower():\n            time.sleep(2 ** attempt)\n            continue\n        raise","preventionTips":["Read the embedded code/status in the message first — this branch is transparent by design and the fix depends on the underlying error","Keep the S3 endpoint reachable from the indexer (egress rules, proxy config) and verify TLS scheme correctness for S3-compatible stores"],"tags":["s3","network","catch-all","validation","diagnostics"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}