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

CosmosDB Rest API调用返回BadRequest错误排查求助

Cosmos DB REST API 查询返回 BadRequest 错误排查

问题背景

按照官方文档编写Python代码,通过REST API从Cosmos DB集合获取单条JSON文档时,返回如下错误:

{'code': 'BadRequest', 'message': 'One of the input values is invalid.\r\nActivityId: <***>, Windows/10.0.17763 cosmos-netstandard-sdk/3.18.0'}

该查询在Cosmos DB UI中执行正常,但错误信息不足以定位问题,相关代码如下:

def query(self, subscription_id, resource_group_name, name, tenant_id, client_id, client_secret, db_account_name, database_name, collection_name, master_key):

    # Start of the code to generate the auth token from master key.
    decoded_master_key = base64.b64decode(master_key)

    resource_type = 'docs'
    resource_id = f'dbs/{database_name}/colls/{collection_name}'

    verb = 'POST'
    date = format_date_time(mktime(datetime.now().timetuple()))
    pain_digest_body = "{verb}\n{resource_type}\n{resource_id}\n{date}\n{other}\n".format(
        verb=(verb.lower() or ''),
        resource_type=(resource_type.lower() or ""),
        resource_id=(resource_id or ""),
        date=date.lower(),
        other="".lower())

    digest_body = pain_digest_body.encode("utf-8")
    digest = hmac.new(decoded_master_key, digest_body, sha256).digest()
    signature = base64.encodebytes(digest).decode("utf-8")

    key_type = 'master'
    version = '1.0'
    master_key_authorization_signature = quote(f'type={key_type}&ver={version}&sig={signature[:-1]}')
    # End of the code to generate the auth token from master key.

    headers = {'x-ms-documentdb-isquery': 'True',
               'x-ms-date': date,
               'authorization': master_key_authorization_signature,
               'x-ms-max-item-count': '1',
               'x-ms-query-enable-crosspartition': 'True',
               'Content-Type': 'application/json',
               'x-ms-version': '2018-09-17',
               'Accept': 'application/json',
               'x-ms-documentdb-query-enable-scan': 'True',
               'x-ms-documentdb-populatequerymetrics': 'True'
               }

    data = {
        'query': f'SELECT * FROM c OFFSET 1 LIMIT 1'
    }

    url = 'https://{}.documents.azure.com/dbs/{}/colls/{}/docs'.format(db_account_name,database_name,
                                                                                             collection_name)

    response = requests.post(url, headers=headers, data=data, timeout=60)

    print(response)

    return response.json()

排查方案及修复

1. 请求体格式错误(最可能原因)

代码中使用requests.post的data=data参数传递查询体,会将字典以application/x-www-form-urlencoded格式编码,但Cosmos DB REST API要求请求体为JSON格式。需改用json=data参数,让requests自动完成JSON序列化,同时确保Content-Type头匹配。

修复后的请求代码:

response = requests.post(url, headers=headers, json=data, timeout=60)

2. 授权签名验证

检查签名生成的关键环节:

  • 日期一致性:确保format_date_time生成的是UTC时区的RFC 1123格式时间(如Fri, 01 Jan 2024 12:00:00 GMT),且与请求头x-ms-date完全一致,不能使用本地时间。
  • 签名字符串拼接:确认pain_digest_body中的换行符为\n,无多余空格;other字段留空符合要求(对应可选的分区键等字段)。
  • 签名编码:base64.encodebytes会在结果末尾添加换行符,signature[:-1]的处理正确,但需确保quote编码后的授权字符串无乱码。

3. 查询体格式规范

按照官方要求,查询请求体需包含parameters字段(即使为空数组),避免格式不兼容:

data = {
    'query': 'SELECT * FROM c OFFSET 1 LIMIT 1',
    'parameters': []
}

4. API版本升级

当前使用的x-ms-version: 2018-09-17版本较旧,尝试升级到较新的稳定版本(如2021-05-15),减少兼容性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 11:27:48