快速结论:该报错通常出现在自托管 Langfuse(docker-compose)时 ClickHouse 迁移失败的任何场景。优先排查 schema_migrations 表的 dirty 状态和数据库连通性,不要被误导性的密码提示带偏;如果密码确实是纯字母数字,基本可以排除密码问题。
适用环境:自托管 Langfuse,官方 docker-compose.yml,镜像 docker.langfuse.com/langfuse/langfuse:4。涉及文件为 web/entrypoint.sh:108-125(ClickHouse 迁移块)和 packages/shared/clickhouse/scripts/up.sh。
最快修复方案:暂无确认的“一键修复”方案,但可优先尝试清理 ClickHouse 中脏迁移状态:连接 ClickHouse 执行 SELECT * FROM default.schema_migrations;,确认 dirty 状态后,将 dirty 字段重置为 0(或删除部分应用的迁移记录),再重启 web 容器。
注意事项:上述修复操作需要手动审查迁移是否部分应用,直接重置 dirty 字段可能掩盖未完成的迁移语句,建议先确认迁移脚本 up.sh 中对应版本的 SQL 是否已完整执行。
问题场景
用户通过官方 docker-compose.yml 自托管 Langfuse,设置纯字母数字密码(如 CLICKHOUSE_PASSWORD=password,无特殊字符)。在 ClickHouse 迁移执行期间中断 Docker 进程(如 Ctrl+C 或容器被 kill),再次启动时 web 容器崩溃,日志中同时出现 “Common cause 2: CLICKHOUSE_PASSWORD … not URL-encoded” 和真实的 Dirty database version 报错。
报错原文
Applying clickhouse migrations failed. Common causes:
1. The database is unavailable or unreachable.
2. CLICKHOUSE_PASSWORD contains special characters that are not URL-encoded.
error: Dirty database version 1. Fix and force version.
原因分析
可能原因:web/entrypoint.sh 中第 121 行附近,将 “CLICKHOUSE_PASSWORD 包含未 URL 编码的特殊字符” 列为每次 ClickHouse 迁移失败的通用原因(无条件打印),而实际检测密码内容的 check_clickhouse_password() 函数是有条件触发的。当密码本身是纯字母数字时,这条提示具有误导性。
本 Issue 的真实故障是:上一次 docker compose up 被中断(容器退出码 137),ClickHouse 迁移 1 正在应用时中断,导致 schema_migrations 表停留在 version=1, dirty=1 状态。ClickHouse 认证全程正常,密码并非问题根因。
环境排查
- 确认 Docker 镜像版本:是否为
docker.langfuse.com/langfuse/langfuse:4(较新版本已移除无条件密码提示,但langfuse:4镜像可能仍包含该逻辑)。 - 确认
CLICKHOUSE_PASSWORD是否确实只包含字母数字(不含& = # ? % + @ space等 URL 不安全字符)。 - 检查 ClickHouse 容器是否可达:
docker compose ps确认 clickhouse 服务状态。 - 检查
schema_migrations表当前状态:SELECT * FROM default.schema_migrations;,关注version和dirty字段。
解决步骤
- 先确认密码不是问题:查看
CLICKHOUSE_PASSWORD是否包含 URL 特殊字符;如果为纯字母数字,直接跳过密码排查。 - 连接 ClickHouse 实例(
docker compose exec clickhouse clickhouse-client或通过 ClickHouse Cloud 控制台),执行SELECT * FROM default.schema_migrations;,查看version和dirty字段。 - 判断 dirty 迁移版本的 SQL 是否已部分应用:比较
up.sh中该版本的 SQL 内容与数据库实际表结构/数据。如果迁移语句只执行了一半,先手动补齐剩余语句;如果完全未执行或不需要执行,可将dirty重置为0。 - 重置脏迁移状态(示例,按实际表名调整):
UPDATE default.schema_migrations SET dirty = 0 WHERE version = 1;(需确认 ClickHouse 的 mutation 语句语法;也可删除该行记录让迁移重新执行)。 - 重启 web 容器:
docker compose restart web(或docker compose up -d),观察日志确认迁移从干净状态重新运行。 - 如果希望避免后续再次被误导,可关注 Langfuse 上游修复:较新版本已移除无条件密码提示(参考 PR #13186 的设计思路——密码提示仅在密码实际包含 URL 不安全字符时显示)。
验证方法
重启 web 容器后,观察日志是否不再出现 Dirty database version 报错,ClickHouse 迁移正常完成,Langfuse 前端可正常访问。同时确认日志中不再出现误导性的 “Common cause 2” 提示(或确认更新到修复版本后该提示已被移除)。
参考来源
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


