DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

MongoDB 连接串报 Password contains unescaped characters:只编码凭据部分

MongoDB URI 密码含特殊字符导致解析失败,分别编码原始用户名和密码,检查重复编码,区分解析、认证与网络故障。

Node.js 创建 MongoDB 客户端时立即报 MongoParseError: Password contains unescaped characters,往往还没有进入服务器认证。用户名或密码里包含 @、:、/ 等字符,直接拼进 URI 会改变连接串结构,应先检查凭据的编码方式。

本文针对将用户名和密码写入 MongoDB URI 的场景。若工具有独立的用户名、密码输入框,应按字段要求填写,不能把 URI 编码后的密码直接替代原密码。

先区分解析失败与认证失败

例如下面这段是错误拼接方式的示例:

const uri = `mongodb://${user}:${password}@db.example.com:27017/app`;

密码中的 @ 会与主机部分的分隔符冲突,/、?、# 等字符也有结构含义。MongoDB URI 中用户名或密码包含 $ : / ? # [ ] @ 时,需要对这些字符做百分号编码。原密码没有变,改变的是 URI 中表示它的方式。

报 Password contains unescaped characters 时,先修复这个解析层。如果改后出现 Authentication failed,说明故障进入认证层,应再核对原始凭据、认证库和认证机制。DNS、连接超时或 TLS 错误则分别检查对应层,不能把所有连接异常都当作密码编码问题。

只编码用户名和密码,不编码整个 URI

JavaScript 可以分别处理原始凭据。以下是结构示例,主机、业务库和认证库需要按实际部署填写:

import { MongoClient } from 'mongodb';

const rawUser = process.env.MONGO_USER;
const rawPassword = process.env.MONGO_PASSWORD;

if (typeof rawUser !== 'string' || typeof rawPassword !== 'string') {
  throw new Error('MongoDB credentials are missing');
}

const user = encodeURIComponent(rawUser);
const password = encodeURIComponent(rawPassword);
const uri = `mongodb://${user}:${password}@db.example.com:27017/app?authSource=admin`;
const client = new MongoClient(uri);

db.example.com 是示例主机;app 是示例业务库,admin 假设为用户实际创建的认证库,不能无条件照搬。SRV URI 也需要正确表示凭据,但主机列表、端口与选项应遵守自己的格式。

编码整个 URI 会把 ://、分隔符和查询参数一并处理,得到的内容不再是原来的连接串。也不要把密码里的特殊字符删掉,那会变成另一份凭据。

检查有没有重复编码

配置系统里应明确保存的是原密码还是完整连接串。如果变量保存原密码,拼接时编码一次;如果已经保存可直接使用的完整 URI,不要再把它当作密码组件编码。

以假设密码 demo@pass 为例,组件编码后的表示是 demo%40pass。若再次编码,百分号会变成 %25,得到 demo%2540pass,驱动解码后拿到的凭据与原密码不同。这些值仅用于说明转换,不是建议采用的密码。

日志中记录错误类型和配置来源即可,不要输出完整 URI、用户名与密码。若连接串曾被打印到共享日志或提交到仓库,应先撤除暴露并按自己的凭据管理流程轮换,而不是仅修改显示方式。

调整后,用应用原来的连接流程验证:URI 能解析,认证成功,账户能够执行预期且获准的数据库操作。仅不再出现解析错误,不代表认证库、网络和权限也已正确;如果后续错误不同,按新错误继续判断。