server.id 必须与profile中repository id严格一致,密码为明文,mirrorof *会绕过认证导致401;实操需复制粘贴id、直接填原始密码、精准配置mirror。

server.id 必须和 profile 中的 repository id 严格一致
这是最常踩的坑:Maven 不会自动关联 settings.xml 里的 <server></server> 和 pom.xml 或 profile 里声明的仓库,只靠 id 字符串完全匹配。一旦拼错、大小写不一致、多空格或用了下划线/短横混用,认证就静默失效,报错却只显示 401 或 “not authorized”,根本看不出是配置没对上。
实操建议:
- 在
pom.xml的<repositories></repositories>或<distributionmanagement></distributionmanagement>里复制出仓库的id值(比如my-nexus) - 直接粘贴到
settings.xml的<server></server>节点内,作为<id>my-nexus</id> - 别手写、别改名、别加前缀(例如不要写成
nexus-my-nexus)
password 是明文,但必须 Base64 解码后能还原原始密码
Maven 官方不支持加密存储密码,<password></password> 字段填的就是服务端实际要求的明文密码 —— 但很多人误以为要填 Base64 编码值,结果输进去后 Maven 尝试 Base64 解码再发给服务器,导致认证失败。
实操建议:
-
<password></password>里直接写你登录私有仓库网页时用的原始密码(例如<password>MyPass123!</password>) - 如果用的是 Nexus,且启用了 LDAP 或 SSO,确认该账号是否支持 basic auth;某些 Nexus 配置下,仅凭用户名密码无法 push,需用 API Token 替代密码
- 敏感项目建议配合
mvn --encrypt-master-password+settings-security.xml加密,但那是另一层机制,不影响<password></password>字段本身的明文语义
privateKey 和 passphrase 配合使用时,passphrase 不能为空字符串
当私有仓库要求 SSH 认证(比如某些自建 Artifactory 或 Nexus 配置了 SSH 接入),<privatekey></privatekey> 指向本地私钥文件路径,<passphrase></passphrase> 是该私钥的解密口令。如果私钥没设口令,<passphrase></passphrase> 节点**必须留空,但不能删掉** —— 删掉会导致 Maven 认为“未提供口令”,从而拒绝加载私钥。
实操建议:
-
<privatekey></privatekey>填绝对路径更稳(如/home/user/.ssh/id_rsa_nexus),避免相对路径在不同工作目录下失效 - 若私钥无口令,写成
<passphrase></passphrase>(空标签),不是<passphrase>null</passphrase>,也不是注释掉 - 确保私钥文件权限为
600,否则 Maven 会跳过加载并静默忽略
mirrorOf * 会覆盖所有仓库,导致 server 认证被绕过
很多团队在 settings.xml 里配了 <mirrorof>*</mirrorof> 把所有请求打到私有仓库,这本身没问题。但副作用是:Maven 会把所有请求(包括中央仓库、JCenter 等)都重定向过去,而这些外部仓库显然没有在 <servers></servers> 里配对应 <server></server> —— 结果就是下载依赖时反复 401,因为请求被发到了私有仓库,却没带任何认证头。
实操建议:
- 把
<mirrorof></mirrorof>改成精准匹配,例如<mirrorof>central,public</mirrorof>,然后在<profiles></profiles>里显式定义central和public对应的仓库 URL - 或者用
<mirrorof>!central,!jcenter,*</mirrorof>排除已知公开源,但注意 Nexus 3.30+ 开始不支持!语法,得换策略 - 运行
mvn help:effective-settings检查最终生效的 mirror 和 server 映射关系,比猜靠谱得多
Maven 的 server 认证本质是一次性绑定,没中间态、不 fallback、不提示错在哪 —— 所以 id 对不上、密码写错、mirror 搞混,都会表现为同一个现象:push 失败或 dependency 下载 401。调的时候别急着改密码或重装插件,先核对这三处:id 是否完全一致、password 是否真明文、mirror 是否把请求导去了没配认证的地址。










