You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Minio Python SDK无法下载CSV/JPG等非文本文件的问题求助

自托管Minio Python客户端下载部分文件报AccessDenied问题排查

问题概述

  • 自托管Minio服务,Python代码无法下载.csv/.jpg/.tar等类型文件,但.txt/.md可正常下载
  • 存储桶策略已设为宽松权限,无文件类型限制;Web门户可正常下载所有类型文件
  • 两种场景均失败:Web上传后代码下载、代码上传后用同一密钥下载

相关代码

class MinioUploader:

    def __init__(self):
        self.minioClient = Minio(
            endpoint="myminio.website.com",
            region="us-east-1",
            access_key="myaccesskeywhichiwillnotputhere",
            secret_key="mysecretketywhichiwillnotputhere",
            secure=True
        )
    def download_all_files(self, bucket_name, local_path="./storage/local_storage/"):
        if self.minioClient is None:
            logs_sys.error("Minio client is not initialized.")
            return

        if not self.minioClient.bucket_exists(bucket_name):
            logs_sys.error(f"Bucket: {bucket_name} does not exist")
            return

        local_path = os.path.join(local_path, bucket_name)
        if not os.path.exists(local_path):
            os.makedirs(local_path)
        print(f"local_path: {local_path}")

        objects = self.minioClient.list_objects(bucket_name, recursive=True)
        for obj in objects:
            try:
                print(obj.object_name)
                # Decode any percent-encoded characters in the object name
                decoded_object_name = unquote(obj.object_name)
                # Create a safe, absolute file path
                safe_local_path = os.path.join(local_path, *decoded_object_name.split('/'))
                # Ensure the directory for the file exists
                safe_local_path = safe_local_path.replace("\\", "/")
                os.makedirs(os.path.dirname(safe_local_path), exist_ok=True)
                # Download the object
                print(f"Downloading {obj.object_name} to {safe_local_path}")
                self.minioClient.fget_object(bucket_name=bucket_name, object_name=obj.object_name, file_path=safe_local_path)
            except Exception as e:
                logs_sys.error(f"Error: {e}")
                print(f"Error: {e}")

报错信息

D:\TRADING_RESTORE_STRATEGIES>python -u "d:\TRADING_RESTORE_STRATEGIES\storage\minio_s3\minio_client.py"
local_path: ./storage/local_storage/testdownloadbucket
11.md
Downloading 11.md to ./storage/local_storage/testdownloadbucket/11.md
3-7-2024 3-11-49 AM.jpg
Downloading 3-7-2024 3-11-49 AM.jpg to ./storage/local_storage/testdownloadbucket/3-7-2024 3-11-49 AM.jpg
Error: S3 operation failed; code: AccessDenied, message: Access denied, resource: /testdownloadbucket/3-7-2024%203-11-49%20AM.jpg, request_id:
 17BACF23766A4250, host_id: dd9025af9251148b658df7ac2e3e8, bucket_name: testdownloadbucket, object_name: 3-
7-2024 3-11-49 AM.jpg
asad.txt
Downloading asad.txt to ./storage/local_storage/testdownloadbucket/asad.txt
new.csv
Downloading new.csv to ./storage/local_storage/testdownloadbucket/new.csv
Error: S3 operation failed; code: AccessDenied, message: Access denied, resource: /testdownloadbucket/new.csv, request_id: 17BACF23839DECB7, h
ost_id: dd9025af9251148b658df7ac2e3e8, bucket_name: testdownloadbucket, object_name: new.csv
something1.csv
Downloading something1.csv to ./storage/local_storage/testdownloadbucket/something1.csv
Error: S3 operation failed; code: AccessDenied, message: Access denied, resource: /testdownloadbucket/something1.csv, request_id: 17BACF238744
C16C, host_id: dd9025af9251148b658df7ac2e3e8, bucket_name: testdownloadbucket, object_name: something1.csv
test.txt
Downloading test.txt to ./storage/local_storage/testdownloadbucket/test.txt
<minio.api.Minio object at 0x00000248C9B0B130>

排查方向与解决方案

1. 升级Minio Python客户端版本

旧版本minio-py可能存在对象名特殊字符(如空格)、非文本文件签名处理的bug,先升级到最新版:

pip install --upgrade minio

2. 替换fget_object为get_object手动写入

尝试绕过fget_object的内部处理逻辑,改用get_object流式写入文件,验证是否为方法本身的问题:
修改代码中下载部分:

# 替换原fget_object代码
response = self.minioClient.get_object(bucket_name, obj.object_name)
with open(safe_local_path, 'wb') as f:
    for chunk in response.stream(1024*1024):
        f.write(chunk)
response.close()
response.release_conn()

3. 检查存储桶策略的隐藏条件

即使策略看起来宽松,可能存在针对Content-Type的限制(比如仅允许text/*类型)。查看桶策略的JSON配置,确认是否存在如下类似条件,如有则删除:

"Condition": {
    "StringEquals": {
        "s3:ContentType": "text/*"
    }
}

4. 验证访问密钥的权限

确认使用的Access Key拥有完全的桶操作权限,而非仅针对特定文件类型。可以直接用管理员密钥测试,排除权限不足问题。

5. 查看Minio服务器端日志

检查Minio控制台或日志文件,获取更详细的权限拒绝原因(比如是桶策略拦截、IAM权限限制还是签名错误),这是定位问题的关键。

6. 测试对象名编码传递

对于包含空格、特殊字符的对象名,尝试直接传递编码后的名称测试:

import urllib.parse
encoded_obj_name = urllib.parse.quote(obj.object_name)
self.minioClient.fget_object(bucket_name, encoded_obj_name, safe_local_path)

内容的提问来源于stack exchange,提问作者the_begging_beginner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 12:07:03