401错误主因是API密钥未正确传递、环境变量未生效、认证方式混淆或权限不匹配。需逐层验证:getenv()是否读取到密钥、AK/SK与Bearer Key是否混用、平台密钥状态及scope是否启用、curl请求头大小写与空格是否规范。

401 Unauthorized 或 API key missing 是 PHP 调用文生图 API 时最常卡住的第一关。这类错误几乎从不表示服务不可用,而是密钥没传对、没读到、或权限不对——直接改代码重试没用,得按路径一层层查。
检查 getenv() 是否真读到了密钥
PHP 里用getenv('FAL_KEY') 或 getenv('VOLC_ACCESS_KEY') 读密钥,但环境变量可能根本没生效。常见现象是本地 echo $FAL_KEY 有值,但 PHP var_dump(getenv('FAL_KEY')) 返回 false 或空字符串。
- Apache 下需在 .htaccess 或虚拟主机配置中显式 SetEnv FAL_KEY "sk-fal-xxx",仅靠 shell export 不起作用
- Nginx + PHP-FPM 需在 php-fpm.conf 或 pool 配置里加 env[FAL_KEY] = sk-fal-xxx
- CLI 模式下确认执行命令的用户与环境变量设置用户一致(比如用 sudo -u www-data php script.php 时,www-data 用户的 ~/.bashrc 里没 export)
- 用 phpinfo() 页面搜索 “Environment” 区域,看目标变量是否真实出现在列表里
区分 AK/SK 和 API Key,别混用认证方式
火山引擎系文生图 API 分两套体系: - 视觉智能服务(Visual Service)用VOLC_ACCESS_KEY + VOLC_SECRET_KEY 签名,必须构造 HMAC-SHA256 请求头,不能只塞一个 Bearer Token
- 火山方舟(Ark)平台用 ARK_API_KEY,走标准 Authorization: Bearer xxx,但必须配对正确的 Endpoint(比如 https://ark.cn-beijing.volces.com/api/v3)
- LiblibAI、Fal.ai、Clawdbot 等第三方服务则只认单一 API Key,且要求放在 Authorization 头,格式为 Bearer sk-fal-xxx 或 Bearer sk-liblib-xxx
混用会导致 400 Bad Request 或 401,且错误信息往往不提示具体哪项错。先确认你调的是哪家的 endpoint,再反推该用哪组凭证。
密钥本身状态与权限是否匹配
密钥字符串看着对,不代表能用: - 登录对应平台控制台,确认密钥Status 是 Active,不是 Revoked 或已过期
- Fal.ai 密钥必须带 image-generation scope;Clawdbot 要求 clawdbot:execute 和 session:read;LiblibAI 密钥需在「文生图」权限开关里手动开启
- 火山引擎 AK/SK 若只开通了对象存储,没开视觉服务,也会返回 403 Forbidden,而非密钥错误
- 用 curl -v -H "Authorization: Bearer $FAL_KEY" https://api.fal.ai/v1/models 手动测一次,绕过 PHP 环境干扰,快速验证密钥有效性
PHP cURL 请求头拼写与编码细节
即使密钥正确,curl_setopt() 设错一行也会失败:
- Authorization 头名必须首字母大写,写成 authorization 或 AUTHORIZATION 在部分服务端会被忽略
- Bearer 后必须有一个空格:"Bearer ".$key,漏掉空格变成 "Bearersk-fal-xxx" 就是无效 token
- 中文 prompt 必须用 json_encode($data, JSON_UNESCAPED_UNICODE),否则默认转义成 \uXXXX,某些 API 解析失败
- Fal.ai 要求 Content-Type: application/json,少设这个头会返回 415 Unsupported Media Type密钥排查最难的点不在“找不到”,而在“以为找到了”。环境变量是否透传、平台权限是否开全、请求头大小写与空格是否精确——这些地方差一个字符,401 就不会变成 200。



















