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

Python处理AWS Kinesis+Lambda CLI事件报UnicodeDecodeError排查

问题背景

已部署开启服务端加密的AWS Kinesis数据流,关联Lambda函数负责事件处理。通过CLI调用put-record接口写入JSON格式测试事件时,Lambda端解析逻辑抛出如下错误:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x99 in position 0: invalid start byte
该配置此前已正常运行数月,未做任何代码变更的情况下约1个月前突然出现该问题。

复现信息

事件写入CLI命令

aws kinesis put-record \
--stream-name "dev" \
--partition-key "user_event" \
--data '
    [{
        "user_id": 2002,
        "group_id": 2002,
        "created_at": "2021-11-24T16:03:03Z",
        "user_event_id": 989898989898,
        "event_type": "in",
        "event_date": "2022-11-03T14:03:03Z",
        "category": "music",
        "is_free": true
    }]' \
--profile dev \
--region eu-central-1

Lambda解析代码

for record in kinesis_data["Records"]:
    partition_key = record["kinesis"]["partitionKey"]

    if not self.accepted_parsers(partition_key):
        continue

    encoded_data = record["kinesis"]["data"]
    payload_string = base64.b64decode(encoded_data)

    payload = json.loads(payload_string)

错误栈信息

[ERROR] UnicodeDecodeError: 'utf-8' codec can't decode byte 0x99 in position 0: invalid start byte
Traceback (most recent call last):
  File "/var/task/events_processing.py", line 38, in lambda_handler
    status_code = lambda_interactor.call(event)
  File "/var/task/lib/lambda_interactor.py", line 113, in call
    event_dicts = self.kinesis_parser.call(payload)
  File "/var/task/lib/kinesis_parser.py", line 22, in call
    payload = json.loads(payload_string)
  File "/var/lang/lib/python3.8/json/__init__.py", line 343, in loads
    s = s.decode(detect_encoding(s), 'surrogatepass')

调试观测结果

  • 获取到的encoded_data丢失了所有JSON格式特殊符号(括号、引号、冒号、逗号、空白符等),仅保留字符串与数字拼接内容
  • base64解码后的payload_string为乱码二进制数据
根因分析

问题出在AWS CLI对二进制参数--data的处理逻辑变更,和Kinesis服务端加密、Lambda逻辑无关:

  1. Kinesis的put-record接口要求Data字段传输base64编码后的二进制内容。
  2. AWS CLI存在cli-binary-format配置项控制二进制参数的处理逻辑:
    • 当值为raw-in-base64-out时,CLI会自动将传入的原始文本/二进制内容做base64编码后提交给接口,符合旧版本CLI的默认行为
    • 当值为base64时,CLI会默认传入的内容已经是base64编码串,会自动过滤所有不在base64合法字符集(A-Za-z0-9+/=)内的字符后直接提交给接口
  3. 传入的格式化JSON包含大量非base64合法字符(换行、空格、括号、引号、冒号、逗号),被CLI过滤后仅剩下字母数字拼接的无效base64串,存入Kinesis。Lambda拿到该无效串做base64解码后自然得到乱码,触发UTF-8解码错误。
  4. 故障突然出现的原因是本地AWS CLI自动更新、或配置文件被修改,导致cli-binary-format的默认值从raw-in-base64-out变为了base64。
修复方案

二选一即可:

  1. 调用CLI时显式指定二进制格式参数,强制CLI自动编码原始内容,和原有行为保持一致:
    在put-record命令中加入参数--cli-binary-format raw-in-base64-out即可。建议同时将传入的JSON压缩为无多余空白的单行字符串,避免不同shell对多行字符串的处理差异。
    修复后的命令示例:
    aws kinesis put-record \
    --stream-name "dev" \
    --partition-key "user_event" \
    --cli-binary-format raw-in-base64-out \
    --data '[{"user_id":2002,"group_id":2002,"created_at":"2021-11-24T16:03:03Z","user_event_id":989898989898,"event_type":"in","event_date":"2022-11-03T14:03:03Z","category":"music","is_free":true}]' \
    --profile dev \
    --region eu-central-1
    
  2. 提前将待写入的JSON内容手动做base64编码,再将编码后的字符串传给--data参数,适配CLI默认的base64输入要求。

如果需要永久修复,可以在AWS CLI配置文件(~/.aws/config)的对应profile下加入如下配置,避免后续其他命令出现同类问题:

cli_binary_format = raw-in-base64-out

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 07:27:21