CERT_HAS_EXPIRED 是 npm 安装依赖时比较典型的证书校验错误,常见报错形式如下:
npm ERR! code CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to https://registry.npm.taobao.org/xxx failed, reason: certificate has expired
这类问题通常并不是项目代码导致的,而是 npm 请求的镜像地址使用了失效、过期或已经不再推荐使用的证书配置。尤其是一些历史项目仍然配置了 registry.npm.taobao.org,就容易遇到证书相关问题。
一、CERT_HAS_EXPIRED到底是什么意思
CERT_HAS_EXPIRED 的含义是“证书已经过期”。
npm 使用 HTTPS 访问软件包仓库时,需要验证服务器提供的 SSL/TLS 证书。如果证书已经超过有效期,Node.js 会拒绝建立安全连接,并返回:
CERT_HAS_EXPIRED
因此,下面这种配置就值得重点检查:
Bashnpm config get registry
如果返回:
https://registry.npm.taobao.org/
说明当前 npm 仍然使用淘宝 npm 镜像的历史域名。
需要注意的是,淘宝 npm 镜像已经迁移到新的域名体系。现在更推荐使用 npmmirror 提供的镜像地址,而不是继续使用历史上的 registry.npm.taobao.org。
二、先检查当前npm镜像地址
执行:
Bashnpm config get registry
正常情况下,可以使用:
https://registry.npmjs.org/
如果希望使用国内镜像,则可以切换到:
https://registry.npmmirror.com/
还可以通过下面的命令查看 npm 当前的完整配置:
Bashnpm config list
重点检查是否存在类似配置:
registry=https://registry.npm.taobao.org/
如果存在,就建议及时修改。
三、解决淘宝镜像证书过期问题
最直接的处理方法是将 npm registry 修改为新的镜像地址:
Bashnpm config set registry https://registry.npmmirror.com/
修改完成后检查:
Bashnpm config get registry
如果看到:
https://registry.npmmirror.com/
说明 registry 已经切换成功。
随后重新安装依赖:
Bashnpm install
如果原来的错误确实是淘宝历史镜像证书问题,一般就可以恢复正常。
四、也可以恢复官方npm源
如果项目并不要求使用国内镜像,可以直接恢复 npm 官方仓库:
Bashnpm config set registry https://registry.npmjs.org/
然后验证:
Bashnpm config get registry
结果应该为:
https://registry.npmjs.org/
再执行:
Bashnpm install
这种方式通常也是最简单、最稳定的解决方案。
五、检查项目中的.npmrc文件
有时候执行:
Bashnpm config set registry ...
之后,npm 仍然访问旧的淘宝镜像。
这通常是因为项目目录中存在 .npmrc。
例如项目根目录存在:
.npmrc
内容可能是:
INIregistry=https://registry.npm.taobao.org/
此时 npm 会按照配置文件的优先级读取 registry,导致全局配置没有达到预期效果。
可以检查项目目录:
Bashdir /a
Windows PowerShell 可以使用:
PowerShellGet-ChildItem -Force
Linux/macOS 可以使用:
Bashls -la
如果发现 .npmrc,打开后检查是否存在:
INIregistry=https://registry.npm.taobao.org/
将其修改为:
INIregistry=https://registry.npmmirror.com/
或者删除这条 registry 配置,让项目使用全局 npm registry。
六、检查用户级.npmrc配置
除了项目目录,用户目录中也可能存在 .npmrc。
可以通过:
Bashnpm config list
查看最终生效的配置。
如果不确定某项配置来自哪里,可以使用:
Bashnpm config get userconfig
查看用户级配置文件的位置。
也可以检查 npm 当前 registry:
Bashnpm config get registry
如果依旧显示:
https://registry.npm.taobao.org/
就需要继续排查项目级、用户级以及其他 npm 配置。
七、检查package-lock.json中的旧地址
部分旧项目除了 .npmrc 使用历史淘宝镜像之外,package-lock.json 中也可能保存了旧的下载地址。
例如可能出现:
JSON"resolved": "https://registry.npm.taobao.org/example-package/-/example-package-1.0.0.tgz"
如果 lock 文件中存在大量历史 registry 地址,可以考虑删除依赖目录和 lock 文件后重新生成。
例如:
Bashrm -rf node_modules package-lock.json npm install
Windows CMD 可以使用:
cmdrmdir /s /q node_modules del package-lock.json npm install
不过,删除 package-lock.json 会重新解析依赖版本,可能造成依赖树发生变化。
对于生产项目,不建议为了处理一个证书问题就直接删除 lock 文件。更稳妥的方式是先修改 registry,再根据实际情况处理 lock 文件。
八、npm cache是否需要清理
很多人遇到 npm 安装错误时第一反应就是清理缓存。
可以执行:
Bashnpm cache clean --force
但需要明确,CERT_HAS_EXPIRED 的核心原因是 HTTPS 证书校验失败,清理 npm cache 并不能直接修复一个已经过期的服务器证书。
因此,更合理的排查顺序应该是:
检查 registry ↓ 发现旧淘宝镜像 ↓ 切换到 npmmirror 或官方 npm ↓ 重新 npm install ↓ 仍然失败时再检查 .npmrc、Node.js 和系统证书
只有在缓存确实存在异常的情况下,再考虑清理缓存。
九、不要通过关闭严格SSL验证来解决
网上经常可以看到这样的解决方法:
Bashnpm config set strict-ssl false
甚至有人建议:
Bashnpm config set strict-ssl false npm install
虽然这样有可能绕过部分 SSL 证书校验问题,但不建议把它作为正常解决方案。
原因很简单:npm 使用 HTTPS 的目的之一就是验证通信安全。如果关闭严格 SSL 校验,就相当于降低了安全防护。
更不推荐使用:
Bashnpm config set registry http://registry.npm.taobao.org/
把 HTTPS 改成 HTTP 并不能真正解决问题,反而可能带来依赖下载过程中的安全风险。
正确思路应该是更换有效的 HTTPS registry,而不是关闭证书验证。
十、Node.js版本过旧也值得检查
如果已经切换到:
https://registry.npmmirror.com/
仍然出现证书错误,就需要检查 Node.js 版本。
执行:
Bashnode -v npm -v
老版本 Node.js 可能包含较旧的 CA 证书集合,在访问现代 HTTPS 服务时可能出现证书链验证问题。
对于长期维护的项目,建议使用仍然获得支持的 Node.js LTS 版本,并根据项目要求选择合适版本。
升级 Node.js 后再次执行:
Bashnpm install
如果项目使用了 nvm,也可以通过 nvm 切换到合适的 Node.js 版本。
十一、检查电脑系统时间
HTTPS 证书验证不仅依赖服务器证书本身,也依赖客户端的系统时间。
例如电脑实际时间明显早于或晚于当前时间,就可能导致正常证书被判断为:
certificate has expired
可以检查:
系统日期 系统时间 时区 自动同步时间
Windows 用户可以打开系统日期和时间设置,确认自动设置时间以及时区是否正确。
如果电脑时间存在明显偏差,修正时间后再尝试:
Bashnpm install
十二、企业网络环境需要检查代理和证书
如果个人电脑使用新 registry 正常,而公司电脑仍然出现:
CERT_HAS_EXPIRED
还需要考虑网络代理、防火墙或 HTTPS 中间人代理。
某些企业网络会对 HTTPS 流量进行代理,并使用企业内部 CA 重新签发证书。
这时 npm 看到的证书并不一定是镜像站直接提供的证书。
可以检查 npm 是否配置了代理:
Bashnpm config get proxy
以及:
Bashnpm config get https-proxy
如果返回了企业代理地址,应结合公司的网络策略进行检查。
不要为了绕过企业证书问题直接关闭:
Bashstrict-ssl
更合理的做法是按照企业网络管理员提供的 CA 证书配置 Node.js/npm 的信任链。
十三、推荐的一套完整排查命令
遇到淘宝镜像 CERT_HAS_EXPIRED 时,可以依次执行:
Bashnode -v npm -v npm config get registry npm config list npm config get proxy npm config get https-proxy
如果 registry 是:
https://registry.npm.taobao.org/
直接切换:
Bashnpm config set registry https://registry.npmmirror.com/
然后确认:
Bashnpm config get registry
最后:
Bashnpm install
如果仍然失败,再检查项目中的 .npmrc、用户级 .npmrc、系统时间、Node.js 版本以及企业代理环境。
十四、如何确认npm镜像已经恢复
修改 registry 后,可以使用 npm 查看当前配置:
Bashnpm config get registry
也可以测试 npm registry 是否可以正常访问:
Bashnpm ping
正常情况下会得到类似:
npm notice PING https://registry.npmmirror.com/ npm notice PONG ...
还可以尝试查看某个常用包:
Bashnpm view lodash version
如果能够正常返回版本号,说明 npm 与 registry 之间的 HTTPS 通信基本恢复正常。
随后再执行:
Bashnpm install
十五、不同场景应该怎么选择
如果只是个人开发环境,推荐直接使用:
Bashnpm config set registry https://registry.npmmirror.com/
如果网络访问 npm 官方源没有问题,则可以使用:
Bashnpm config set registry https://registry.npmjs.org/
如果是团队项目,建议把 registry 配置策略统一下来,避免开发人员分别使用不同的历史镜像。
如果是 CI/CD 环境,还应该检查构建服务器中的 .npmrc、环境变量以及 npm 配置,不能只修改本地电脑。
十六、常见误区
1. 认为npm版本导致CERT_HAS_EXPIRED
npm 版本可能影响网络请求行为,但如果错误明确指向:
CERT_HAS_EXPIRED
首先应该检查访问的 HTTPS 地址以及对应证书,而不是盲目升级 npm。
2. 直接关闭strict-ssl
Bashnpm config set strict-ssl false
这种做法属于降低安全校验,并没有从根本上解决镜像证书问题。
3. 继续使用registry.npm.taobao.org
历史项目中经常可以看到:
https://registry.npm.taobao.org/
但这并不意味着今天仍然应该继续使用该地址。对于新项目,更应该使用当前有效且受支持的 registry 地址。
4. 一遇到错误就删除package-lock.json
lock 文件承担着锁定依赖版本的重要作用。
如果只是 registry 证书问题,没有必要首先删除 package-lock.json。应该优先修复 registry 配置。
十七、推荐解决方案
对于典型的淘宝镜像证书过期问题,可以按照下面的方式处理:
Bashnpm config set registry https://registry.npmmirror.com/ npm config get registry npm ping npm install
如果仍然报错,再检查:
项目 .npmrc 用户 .npmrc package-lock.json Node.js版本 系统时间 npm代理配置 企业HTTPS代理
不要优先选择关闭 SSL 校验或改用 HTTP。
CERT_HAS_EXPIRED 看起来是一个简单的 npm 报错,但真正解决问题的关键并不是反复执行 npm install,而是找到 npm 实际访问的 registry,并确认客户端能够正确验证该 HTTPS 服务的证书。对于仍然使用 registry.npm.taobao.org 的旧项目,将 registry 更新为 https://registry.npmmirror.com/ 或 npm 官方源,通常是最直接、也更符合安全实践的处理方式。