Firebase Functions向Google Cloud Tasks添加任务报NOT_FOUND错误
问题表现
- 代码侧通过Firebase Functions向Google Cloud Tasks添加任务时返回错误码5,报错信息为
Requested entity was not found - 已确认目标队列真实存在,使用gcloud命令行执行入队操作可正常运行,无异常
- 核心错误栈:
Error: 5 NOT_FOUND: Requested entity was not found. at Object.callErrorFromStatus (/workspace/node_modules/@grpc/grpc-js/build/src/call.js:31:26) at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client.js:189:52) at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:365:141) at Object.onReceiveStatus (/workspace/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:328:181) at /workspace/node_modules/@grpc/grpc-js/build/src/call-stream.js:187:78 at processTicksAndRejections (node:internal/process/task_queues:78:11)
根因排查顺序(按出现概率从高到低)
检查队列完整路径格式
Cloud Tasks的gRPC接口不会自动补全路径参数,代码中传入的队列名必须严格遵循完整格式:projects/<项目ID>/locations/<队列部署区域>/queues/<队列名称>。
这类问题占该报错的90%以上:漏写区域字段、区域和队列实际部署区域不匹配、项目ID填错、队列名单词拼写错误都会触发这个报错。gcloud命令行能正常执行是因为工具会自动从本地配置读取默认项目、区域参数补全路径,和代码侧的传参逻辑不一样。
最快验证方式:把代码中实际传给客户端的队列路径打印到日志,和gcloud执行成功时用的队列路径逐字符对比。检查服务账号权限绑定
确认Firebase Functions运行时使用的服务账号(默认是<项目ID>@appspot.gserviceaccount.com)已经绑定了Cloud Tasks Enqueuer角色,且角色绑定的范围覆盖目标队列资源。如果是跨项目调用队列,需要在队列所属项目中给该服务账号授权,不要在函数所在项目授权。检查客户端初始化配置
如果初始化Cloud Tasks客户端时手动指定了服务端点/区域参数,需要确认参数值和队列所在区域完全匹配。比如队列部署在asia-northeast1,客户端初始化时填了us-central1,客户端会向美区节点发请求,自然找不到其他区域的队列。检查冷启动路径拼接时序
不要在函数冷启动的全局作用域拼接依赖环境变量的队列路径,部分Firebase Functions运行时在冷启动初始化阶段还未注入项目ID、区域等环境变量,会导致拼接出的队列路径缺字段。把客户端初始化、队列路径拼接逻辑移到函数触发后的执行逻辑里即可规避。
排查提示:如果路径、权限、区域都确认没问题,可以先在函数里用admin权限临时调用项目的队列列表接口,打印返回的所有队列全路径,和自己代码里写的路径做对比,能快速定位路径拼写问题。
内容的提问来源于stack exchange,提问作者Kawaljeet Singh

