常见错误速查
CloudBase PostgreSQL 数据库使用过程中出错时,多半涉及 GRANT / RLS Policy / JWT 三层。本文按「错误现象 → 根因 → 排查」的格式列出常见问题,方便快速定位。
💡 阅读建议:先从「快速排查决策树」入手定位大类问题,再翻具体小节。
快速排查决策树
请求失败 / 拿不到数据
│
├─ HTTP 401 ? → JWT 缺失 / 过期 / 签名错误 → 见 [§ JWT 与认证](#jwt)
├─ HTTP 403 ? → 表级 GRANT 不足 → 见 [§ 表级 GRANT](#grant)
│ → 或 RLS WITH CHECK 拒绝写入
├─ HTTP 404 ? → 表 / RPC 函数不存在 → 见 [§ 资源不存在](#not-found)
├─ HTTP 406 ? → 单对象返回不符合数量约束 → 见 [§ 返回格式](#return-format)
├─ HTTP 409 ? → 唯一约束 / 外键冲突 → 检查表约束
├─ HTTP 500 ? → 函数内 RAISE / 实例错误 → 见 [§ 内部错误](#internal)
└─ 200 但数据空 ? → RLS 静默过滤 → 见 [§ RLS 静默过滤](#silent)
JWT 与认证
401 Unauthorized / JWT expired
| 现象 | 根因 | 排查 |
|---|---|---|
完全未带 Authorization Header | 客户端忘记携带 | 前端确保使用 SDK(自动携带)或手动添加 Authorization: Bearer <token> |
JWT expired | access_token 过期 | 前端调用刷新或重新登录;Publishable Key / API Key 永不过期 |
Invalid JWT | 签名错误、Token 被篡改 | 检查是否复制粘贴时混入空格、换行;确认环境 ID 与 Token 中 aud / project_id 匹配 |
iss claim mismatch | 跨环境使用了别的环境的 Token | 前端环境 ID 必须与 Token 签发环境一致 |
检查当前 Token 中的 role / sub
最快的方法是用 jwt.io 或后端解码(不验签):
echo "<your-jwt>" | awk -F. '{print $2}' | base64 -d 2>/dev/null
应能看到 role: "anon" | "authenticated" | "service_role" 与 sub: "<uuid>"。
表级 GRANT
permission denied for table xxx
ERROR: permission denied for table todos
| 根因 | 排查 |
|---|---|
| 角色没有对应 DML 的 GRANT | \dp public.todos 检查;按需 GRANT SELECT/INSERT/UPDATE/DELETE ON public.todos TO <role>; |
| RLS Policy 已写但漏掉 GRANT | RLS 是第二层,GRANT 是第一层。两层都要过 |
| 用了非业务角色 | 应用流量必须落到 anon / authenticated / service_role 三者之一,其他系统角色不可用 |
permission denied for sequence xxx_id_seq
ERROR: permission denied for sequence todos_id_seq
原因:serial / bigserial 主键背后是 SEQUENCE 对象,授予表的 INSERT 不会自动授予 sequence 权限。
修复:
GRANT USAGE, SELECT ON SEQUENCE public.todos_id_seq TO authenticated;
GRANT USAGE, SELECT ON SEQUENCE public.todos_id_seq TO service_role;
一个表的 sequence 名通常是
<table>_<column>_seq,可用\ds public.*查看。