Python连接Amazon S3被拒绝?运行S3客户端代码报getaddrinfo失败
报错根因分析
该报错并非Amazon S3主动拒绝连接,getaddrinfo failed属于DNS解析失败,代表请求的域名完全不存在,系统无法定位对应服务器的IP,根本未进入和S3服务建立连接的阶段。
核心错误:S3端点域名拼接规则错误
你代码中endpoint的拼接分隔符完全写错,直接导致请求域名不存在:
- 你当前的拼接逻辑:
's3-{}-amazonaws.com'.format(region),生成的端点为s3-ap-south-1-amazonaws.com - S3官方规定的虚拟托管风格端点格式:
s3.{region}.amazonaws.com,所有分隔符必须用.,不能用-
最终拼接出的请求host为mybuceqeqwqxket.example.com.s3-ap-south-1-amazonaws.com,该域名在公网DNS中无任何解析记录,自然触发解析失败。
其他潜在问题(修复DNS错误后会触发)
- 协议不匹配:S3默认仅支持HTTPS请求,代码中使用的
http://前缀会被直接拒绝 - 虚拟托管风格适配问题:使用的bucket名
mybuceqeqwqxket.example.com包含多级点号,若采用bucket名作为子域名的虚拟托管风格请求,会触发SSL证书校验失败(S3的泛域名证书仅匹配一级子域,不匹配带多级点的子域名) - 请求体格式错误:代码中给
CreateBucketConfiguration根节点显式添加xmlns属性,不符合S3 API规范,会被识别为请求格式错误。
修复方案
- 修正endpoint拼接逻辑,将代码中endpoint的定义行改为:
endpoint = 's3.{}.amazonaws.com'.format(region) - 修正请求协议,将URL构造行从
http://改为https://:url = 'https://{}.{}'.format(bucket, endpoint) - 可选二选一解决bucket名带点的适配问题:
- 方案A:将bucket名修改为不含多级点的格式,比如把
mybuceqeqwqxket.example.com改成mybuceqeqwqxket-example-com,符合虚拟托管风格的证书校验要求 - 方案B:改用路径风格的请求方式,把URL构造改为
url = 'https://{}/{}'.format(endpoint, bucket),不再将bucket名作为子域名拼接,避免证书问题
- 方案A:将bucket名修改为不含多级点的格式,比如把
- 修正XML请求体的构造逻辑,将xmlns作为根节点的默认命名空间传入,修改后的XML构造代码为:
XML = ET.Element('CreateBucketConfiguration', xmlns=ns) location = ET.SubElement(XML, 'LocationConstraint') location.text = auth.region - 确认bucket名符合S3规则:全局唯一(不能与其他AWS用户的bucket重名)、全小写、仅包含字母、数字、点、横杠,长度3-63字符,无大写字符、下划线等特殊内容。
内容的提问来源于stack exchange,提问作者killerprince182
相关产品推荐
相关产品推荐

