项目页面因名称查找失败显示“Forbidden”
问题描述
某些 Harbor 项目在访问仓库或其他项目详情时,Web UI 会显示 forbidden 错误。API 返回 403:
其他项目可以正常工作。该问题可能在 Harbor 升级后出现。
根本原因
数据库 project 表中存储的项目名称已损坏(例如存在不可见字符或编码问题)。当 Harbor 通过 ORM 按名称查询项目时:
由于相等性检查失败,查询不会返回任何行,尽管该行实际存在,并且可以通过 project_id 找到。由于项目查找失败,权限检查返回 false,API 因此返回 403 Forbidden,而不是实际数据。
相关上游问题:https://github.com/goharbor/harbor/issues/15620
故障排查
步骤 1:检查 Harbor Core 日志
在 harbor-core 日志中查找以下错误模式:
完整的日志链通常如下所示:
步骤 2:在数据库中验证
连接到 Harbor 数据库(registry):
执行以下查询:
如果第一条查询返回了项目,但第二条返回 0 行,则可以确认该问题。
解决方案
在 Harbor 数据库(registry)中,使用 project_id 重写 name 字段:
验证修复结果:
刷新 Harbor Web UI,确认 403 错误已解决。
REINDEX 风险说明
REINDEX TABLE project 会重建 project 表上的所有索引。它是一项非破坏性操作(不会修改任何数据行),但需要注意以下风险:
建议:
- 在生产环境中,请在低流量维护窗口期间执行,以尽量减小写锁带来的影响。
- 对于
project表本身而言,数据量通常很小(几十到几百行),因此锁定持续时间通常可以忽略不计。 - 如果需要零停机,PostgreSQL 12+ 支持
REINDEX TABLE CONCURRENTLY project,它可以在不持有独占锁的情况下构建新索引。不过,该方式耗时更长,并且需要更多磁盘空间。