错误码排障手册
本页把 43 个错误码按“谁的问题、能不能重试、先查什么”重新组织成排障手册。错误码数值、HTTP 状态、分类与可重试标记都直接来自冻结契约;排障建议是运营经验,不改变契约语义。
响应包络速查
HTTP(Open API / 客户端 REST):{code,msg?,data?,requestId?},code=0 表示成功。
WebSocket:{id?,type:"error",data:{code,message}};SDK 会把错误投递到回调/Promise 的 code。
可重试错误共 9 个:1008、1025、2001、2002、2003、2004、3001、3002、3003。其余错误重试不会变好,先修参数/权限/状态。
排障决策树
- 先看 code 的首位
1xxx是请求/权限/状态类(不可重试,除1008);2xxx是服务端/依赖类(可重试);3xxx是 SDK 本地错误(未连接/超时/网络/不支持)。 - 再区分“重试有没有用”
只有标记为可重试的错误才进入退避重试;重试时必须复用同一
clientMsgId(10 分钟幂等)。 - 最后定位资源状态
1012/1013/1014是聊天室生命周期与成员关系;1005/1006/1009是群;1004/1016是用户。按资源维度查一次即可。 - 记录 requestId
Open API 的
requestId是排查服务端问题的唯一定位符;报障时附上它、时间、appkey、operationId 与请求体(脱敏)。
1xxx:请求 / 权限 / 状态
| 码 | 名称 | 中文 | HTTP | 可重试 | 先查什么 |
|---|---|---|---|---|---|
1001 | INVALID_PARAMETER | 参数错误 | 400 | 否 | 按接口页字段表逐项校验;注意 userId/name 1–64 字符、批量接口上限、未知枚举值 |
1002 | INVALID_TOKEN | Token 无效或已过期 | 401 | 否 | Token 过期或签名域不匹配:重新签发 Token 再 connect;不要复用其他用户的 Token |
1003 | FORBIDDEN | 无权限 | 403 | 否 | 调用者无权限:确认操作者是发送者/群主/管理员/房主;服务端代操作时检查 operatorId |
1004 | USER_NOT_FOUND | 用户不存在 | 404 | 否 | 目标用户不存在:先 user.register 或 user.batch.get 校验 |
1005 | GROUP_NOT_FOUND | 群组不存在 | 404 | 否 | 群不存在:先创建群;检查 groupId 拼写与 appkey 是否一致 |
1006 | NOT_GROUP_MEMBER | 未加入群组 | 403 | 否 | 未加入群:先拉人入群或让用户先 join |
1007 | MESSAGE_TOO_LARGE | 消息体过大(上限 5KB) | 400 | 否 | 消息体超过 5KB:精简 content 或改为短链/文件消息 |
1008 | RATE_LIMITED | 发送过于频繁 | 429 | 是 | 发送过于频繁(可重试):按 Retry-After 退避,客户端做本地节流 |
1009 | GROUP_MUTED | 你已被禁言 | 403 | 否 | 当前用户被禁言:等待解禁或按业务规则提示 |
1010 | SENSITIVE_WORD | 内容包含敏感词 | 400 | 否 | 内容命中敏感词:按控制台处置动作(block/replace)提示用户 |
1011 | BLOCKED | 已被对方拉黑或你已拉黑对方 | 403 | 否 | 双向黑名单:检查好友/黑名单关系,提示不可发送 |
1012 | CHATROOM_NOT_FOUND | 聊天室不存在 | 404 | 否 | 聊天室不存在:先创建;核对 chatroomId |
1013 | CHATROOM_CLOSED | 聊天室已销毁 | 410 | 否 | 聊天室已销毁:不可再使用,重建房间并更新业务映射 |
1014 | NOT_CHATROOM_MEMBER | 未加入聊天室 | 403 | 否 | 未加入聊天室或被封禁:先 join 并等待 chatroom_joined;被封禁则不可再加入 |
1015 | MEMBERSHIP_LIMIT | 成员数量超出上限 | 400 | 否 | 成员数超出上限:普通群 3000、超级群 100000;改用超级群 |
1016 | USER_BANNED | 账号已被封禁 | 403 | 否 | 账号被封禁:停止发送;运营解封后重试 |
1017 | APP_DISABLED | 应用已停用 | 403 | 否 | 应用已停用:检查控制台应用状态 |
1018 | INVALID_SIGNATURE | 签名错误 | 401 | 否 | 签名错误:按 AppSecret+Nonce+Timestamp 重算 hex(sha1),注意小写与时间戳毫秒 |
1019 | TIMESTAMP_EXPIRED | 时间戳超出允许窗口 | 401 | 否 | 时间戳超出 ±300000ms 窗口:校准系统时间后重试 |
1020 | NONCE_REPLAYED | Nonce 重复 | 401 | 否 | Nonce 重复:每次请求重新生成 8–64 字符随机串 |
1021 | SERVICE_NOT_ACTIVATED | 服务未开通 | 403 | 否 | 服务未开通:到控制台「服务开通」开启对应服务后重试 |
1022 | RECALL_EXPIRED | 超过撤回时限 | 400 | 否 | 超过撤回时限:默认 120 秒;应用侧强制撤回需 isAdmin=true |
1023 | MESSAGE_ALREADY_RECALLED | 消息已撤回 | 400 | 否 | 消息已撤回:不要重复撤回,按已撤回状态渲染 |
1024 | CALLBACK_INVALID | 回调配置无效 | 400 | 否 | 回调配置无效:检查 URL(生产必须 https)、事件列表、secret 与重试参数 |
1025 | QUOTA_EXCEEDED | 超出配额 | 429 | 是 | 超出配额(可重试):检查控制台配额与调用量,必要时提额 |
1026 | MESSAGE_NOT_EXPANDABLE | 消息不可扩展(发送时未开启可扩展,或会话类型不支持) | 400 | 否 | 消息不可扩展:发送时未开启可扩展或会话类型不支持;改用业务透传字段 |
1027 | EXPANSION_LIMIT_EXCEEDED | 消息扩展超出限制(单次 20 对 / 单条 300 对 / 键值长度) | 400 | 否 | 消息扩展超限:单次 ≤20 对 / 单条 ≤300 对,检查键值长度 |
1028 | REACTION_INVALID | 回应标识非法(1-16 字符) | 400 | 否 | 回应标识非法:1–16 字符 |
1029 | REACTION_LIMIT_EXCEEDED | 单条消息回应种类超出上限(50) | 400 | 否 | 单条消息回应种类超限:≤50 种 |
1030 | REACTION_USER_LIMIT_EXCEEDED | 单个回应参与用户超出上限(100) | 400 | 否 | 单个回应参与用户超限:≤100 人 |
1031 | TAG_LIMIT_EXCEEDED | 单用户会话标签数超过上限(20) | 400 | 否 | 标签数量超限:≤20 个,每个 ≤32 字符 |
1032 | TAG_NOT_FOUND | 标签不存在 | 404 | 否 | 标签不存在:先查询再删除 |
1033 | TAG_CONVERSATION_LIMIT_EXCEEDED | 标签内会话数超过上限(1000) | 400 | 否 | 会话标签数量超限 |
1034 | CONVERSATION_NOT_FOUND | 会话不存在(标签内置顶等操作要求会话已在标签内) | 404 | 否 | 会话不存在:先发消息或用会话列表确认 |
1035 | MESSAGE_REJECTED_BY_CALLBACK | 发送前同步回调拒绝该消息(应用服务器返回 action=block,或降级配置为 block) | 403 | 否 | 发送前同步回调拒绝:按回调 reason 提示;不要自动重试同一内容 |
2xxx:服务端 / 依赖(可重试)
| 码 | 名称 | 中文 | HTTP | 可重试 | 先查什么 |
|---|---|---|---|---|---|
2001 | INTERNAL_ERROR | 服务端内部错误 | 500 | 是 | 服务端内部错误(可重试):退避重试并记录 requestId |
2002 | DEPENDENCY_UNAVAILABLE | 依赖服务不可用 | 503 | 是 | 依赖服务不可用(可重试):检查数据库/回调等依赖健康度 |
2003 | STORAGE_ERROR | 存储错误 | 500 | 是 | 存储错误(可重试):检查磁盘与数据目录权限 |
2004 | CALLBACK_DELIVERY_FAILED | 回调投递失败 | 502 | 是 | 回调投递失败(可重试):查回调日志与接收端状态 |
3xxx:SDK 本地错误
| 码 | 名称 | 中文 | HTTP | 可重试 | 先查什么 |
|---|---|---|---|---|---|
3001 | SDK_NOT_CONNECTED | 长连接未就绪 | 0 | 是 | SDK 长连接未就绪:先 connect 并等待 CONNECTED 再发送 |
3002 | SDK_TIMEOUT | 请求超时 | 0 | 是 | 请求超时:检查网络与 join/发送超时;可重试 |
3003 | SDK_NETWORK_ERROR | 网络错误 | 0 | 是 | 网络错误:监听 DISCONNECT 并在重连成功后重发(用同一 clientMsgId) |
3004 | SDK_UNSUPPORTED | 当前平台不支持该能力 | 0 | 否 | 当前平台不支持该能力:查平台能力矩阵或改用服务端接口 |
重试策略(只对可重试错误)
JavaScript
// Web SDK:统一处理 RcResult / 异常(同一 clientMsgId 重试,服务端 10 分钟幂等)
async function sendWithRetry(client, type, targetId, content, clientMsgId) {
const delays = [200, 800, 2000]; // 指数退避 + 抖动在实际业务里自行加入
for (let attempt = 0; attempt <= delays.length; attempt++) {
const res = await client.sendMessage(type, targetId, content, { clientMsgId });
if (res.code === 0) return res.data;
if (![1008, 1025, 2001, 2002, 2003, 2004, 3002, 3003].includes(res.code)) {
throw Object.assign(new Error(res.msg), { code: res.code });
}
if (attempt === delays.length) throw Object.assign(new Error('retry exhausted'), { code: res.code });
await new Promise((r) => setTimeout(r, delays[attempt]));
}
}| 错误码 | 退避建议 | 备注 |
|---|---|---|
1008 | 按响应头 Retry-After(默认 1s);无头时 200ms 起指数退避 | 客户端先做本地节流(120 条/分钟/用户) |
1025 | 指数退避,检查控制台配额 | 配额类错误不要高频重试 |
2001/2002/2003/2004 | 500ms 起、最多 3 次,带抖动 | 记录 requestId;持续失败升级告警 |
3002/3003 | 先恢复连接,再重发;不要并发重试 | 用 CONNECTED 事件驱动重发 |
按场景快速定位
| 现象 | 最可能错误码 | 下一步 |
|---|---|---|
| 发送消息失败 | 1008 / 1009 / 1010 / 1007 / 3001 | 看是否禁言/敏感词/超长/未连接;1008 退避 |
| 进不了群/聊天室 | 1005 / 1012 / 1013 / 1014 / 1015 | 先确认资源存在、未销毁、已加入、人数未超限 |
| 服务端签名失败 | 1018 / 1019 / 1020 | 核对 secret、时间戳毫秒、Nonce 唯一性 |
| 接口一直 1021 | 1021 | 控制台服务开通;功能开关是否关闭 |
| 回调收不到/失败 | 1024 / 2004 | 回调 URL/secret/事件订阅;投递日志与重试 |
| SDK 报 3004 | 3004 | 该平台未实现该能力;查平台能力矩阵或改用 REST |