Lambda触发S3上传报错:无法获取S3对象元数据,求排查方案
问题排查与解决方案
核心问题分析
你遇到的问题大概率是S3事件传递的对象键(Key)存在URL编码,导致Rekognition用编码后的Key找不到实际对象;另外代码中硬编码桶名的做法也可能引发潜在问题。
具体解决步骤
1. 解码URL编码的对象键
浏览器上传文件时,S3触发事件中的key会自动进行URL编码(比如空格会变成%20或+),而你硬编码的是原始未编码的Key,所以会出现差异。需要对事件中的Key进行解码:
修改代码,导入urllib.parse并解码Key:
import json import boto3 from urllib.parse import unquote_plus def lambda_handler(event, context): # 获取桶名和解码后的对象键 bucket = event['Records'][0]['s3']['bucket']['name'] key = unquote_plus(event['Records'][0]['s3']['object']['key']) location = key[:17] s3Client = boto3.client('s3') client = boto3.client('rekognition', region_name='us-east-1') # 使用事件中获取的桶名,而非硬编码值 response = client.detect_text(Image={'S3Object': {'Bucket': bucket, 'Name': key}}) detectedText = response['TextDetections']
2. 替换硬编码的桶名
代码中硬编码了'myarrowbucket',但实际触发Lambda的桶名是从事件中获取的bucket变量,两者不一致时会直接导致Rekognition找不到对象。改用事件中获取的桶名可以避免这类问题。
3. 排查权限与区域配置(可选)
如果上述修改后仍报错,检查以下两点:
- IAM权限:确认Lambda执行角色拥有
s3:GetObject和rekognition:DetectText权限,同时S3桶策略未阻止Rekognition访问对象。 - 区域一致性:确保S3桶的区域与Rekognition客户端指定的
us-east-1一致,跨区域访问可能引发权限或延迟问题。
4. 验证对象上传完整性(可选)
若上传大文件,检查Lambda触发器是否监听了ObjectCreated:CompleteMultipartUpload事件(分段上传完成触发),避免在对象未完全写入时执行Rekognition调用。
内容的提问来源于stack exchange,提问作者lb2020
相关产品推荐
相关产品推荐

