{"record":{"id":"7464152164d4f41c","repo":"infiniflow/ragflow","slug":"google-cloud-storage","errorCode":null,"errorMessage":"Google Cloud Storage","messagePattern":"Google Cloud Storage","errorType":"validation","errorClass":"ConnectorMissingCredentialError","httpStatus":null,"severity":"critical","filePath":"common/data_source/blob_connector.py","lineNumber":107,"sourceCode":"            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)\n\n        # Detect bucket region (only important for S3)\n        if self.bucket_type == BlobType.S3:\n            self.bucket_region = detect_bucket_region(self.s3_client, self.bucket_name)","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/common/data_source/blob_connector.py#L89-L125","documentation":"For BlobType.GOOGLE_CLOUD_STORAGE, load_credentials requires both access_key_id and secret_access_key (S3-compatible GCS interoperability keys); missing either raises ConnectorMissingCredentialError('Google Cloud Storage').","triggerScenarios":"GCS connector config where access_key_id or secret_access_key is absent/empty during load_credentials.","commonSituations":"Users trying GCP service-account JSON instead of interoperability keys (the connector expects HMAC keys here); blank fields; key names copied from AWS style (aws_access_key_id) instead of GCS style.","solutions":["Create HMAC keys in GCP: Cloud Storage → Settings → Interoperability, and copy Access Key + Secret","Supply them as access_key_id and secret_access_key exactly","If you only have a service-account JSON, generate interoperability keys for that account first"],"exampleFix":"// before\ncreds = {\"access_key_id\": \"GOOG...\"}  # secret missing\n\n// after\ncreds = {\"access_key_id\": \"GOOG...\", \"secret_access_key\": \"bGbF...\"}","handlingStrategy":"validation","validationCode":"if not (creds.get(\"access_key_id\") and creds.get(\"secret_access_key\")):\n    raise ValueError(\"GCS blob storage needs access_key_id and secret_access_key (HMAC interoperability keys)\")","typeGuard":"def is_gcs_cred_dict(x) -> bool:\n    \"\"\"True when x carries both non-empty GCS interoperability keys.\"\"\"\n    return (\n        isinstance(x, dict)\n        and isinstance(x.get(\"access_key_id\"), str) and x[\"access_key_id\"].strip() != \"\"\n        and isinstance(x.get(\"secret_access_key\"), str) and x[\"secret_access_key\"].strip() != \"\"\n    )","tryCatchPattern":"try:\n    blob.load_credentials(creds)\nexcept ConnectorMissingCredentialError as e:\n    if \"Google Cloud Storage\" in str(e):\n        creds = create_gcs_hmac_keys_and_refill()  # Cloud Storage -> Settings -> Interoperability\n        blob.load_credentials(creds)","preventionTips":["Use GCS interoperability (HMAC) keys, not service-account JSON, for this connector","Copy both key parts together from the Interoperability tab","Validate the credential dict shape at config-save time"],"tags":["gcs","credentials","configuration","blob-storage"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}