{"record":{"id":"c5f8f4e439e1655b","repo":"BerriAI/litellm","slug":"missing-boto3-to-call-s3-run-pip-install-boto3","errorCode":null,"errorMessage":"Missing boto3 to call S3. Run 'pip install boto3'.","messagePattern":"Missing boto3 to call S3\\. Run 'pip install boto3'\\.","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"litellm/integrations/s3_v2.py","lineNumber":589,"sourceCode":"\n    async def _download_object_from_s3(self, s3_object_key: str) -> dict | None:\n        \"\"\"\n        Download and parse JSON object from S3.\n\n        Args:\n            s3_object_key: The S3 object key to download\n\n        Returns:\n            Optional[dict]: The parsed JSON object or None if not found/error\n        \"\"\"\n        try:\n            import hashlib\n\n            import requests\n            from botocore.auth import S3SigV4Auth\n            from botocore.awsrequest import AWSRequest\n        except ImportError:\n            raise ImportError(\"Missing boto3 to call S3. Run 'pip install boto3'.\")\n\n        try:\n            from litellm.litellm_core_utils.asyncify import asyncify\n\n            # Get AWS credentials\n            asyncified_get_credentials: Final = asyncify(self.get_credentials)\n            credentials: Final = await asyncified_get_credentials(\n                aws_access_key_id=self.s3_aws_access_key_id,\n                aws_secret_access_key=self.s3_aws_secret_access_key,\n                aws_session_token=self.s3_aws_session_token,\n                aws_region_name=self.s3_region_name,\n                aws_session_name=self.s3_aws_session_name,\n                aws_profile_name=self.s3_aws_profile_name,\n                aws_role_name=self.s3_aws_role_name,\n                aws_web_identity_token=self.s3_aws_web_identity_token,\n                aws_sts_endpoint=self.s3_aws_sts_endpoint,\n            )\n","sourceCodeStart":571,"sourceCodeEnd":607,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/integrations/s3_v2.py#L571-L607","documentation":"The S3 download path (reading back a logged object, e.g. for the /spend or log-retrieval features) also does lazy imports of requests + botocore signing classes and raises ImportError when they are missing. Unlike its two siblings, this message correctly says 'call S3'. It fires only when a download is attempted, so installs can run for a long time before hitting it.","triggerScenarios":"Configuring the s3_v2 logger for writes (uploads work because boto3 happens to be present in the writer path's env) and later invoking a read/replay endpoint that triggers download_data_from_s3; mixed environments where only some processes lack botocore.","commonSituations":"Write-path tested at deploy time but read path (spend reconstruction, log inspection) exercised later; worker containers with trimmed dependencies; local dev with a different venv than the proxy.","solutions":["pip install boto3 requests (or litellm[extra_proxy]) wherever reads happen","Smoke-test the read path after install: fetch one known s3 object key through the logger","Pin the deps in your deploy manifest so they cannot be pruned by dependency-resolution tools"],"exampleFix":"# before: read endpoint 500s with ImportError: Missing boto3 to call S3\n# after\n# python -m pip install boto3 requests\n# verify:\n#   python -c \"from botocore.auth import S3SigV4Auth; import requests\"","handlingStrategy":"validation","validationCode":"def can_download_from_s3() -> bool:\n    try:\n        import requests\n        from botocore.auth import S3SigV4Auth  # noqa: F401\n        return True\n    except ImportError:\n        return False\n\nif not can_download_from_s3():\n    raise RuntimeError(\"boto3/botocore required for S3 log retrieval\")","typeGuard":null,"tryCatchPattern":"try:\n    obj = await s3_logger.download_data_from_s3(s3_object_key)\nexcept ImportError as e:\n    if \"Missing boto3\" in str(e):\n        obj = None\n        logger.warning(\"S3 read path unavailable: install boto3\")\n    else:\n        raise","preventionTips":["Smoke-test the S3 read path (not just writes) after deployment","Pin boto3 in requirements and scan images for it in CI","Note this import is lazy — a long-running process only discovers the gap on the first read"],"tags":["s3","dependency","botocore","download"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}