Fedora 安装软件报 404 错误 从更换国内镜像源到解决依赖缺失的完整配置指南
最近装了台新机器跑 Fedora 39,刚打开终端准备装个日常用的软件,结果 dnf install 直接抛出一堆 404 报错,心态直接崩了。国内用 Fedora 的朋友基本都踩过这个坑——官方源在国外,下载速度龟速不说,偶尔还会抽风导致元数据丢失,最后就是各种依赖找不到包。我折腾了整整一个下午,查了无数文档、论坛帖子,终于把这事儿彻底搞明白了。今天把完整流程整理出来,顺便把里面的一些坑也标清楚,希望帮你少走弯路。
为什么 Fedora 会报 404?
在动手改任何东西之前,先理解根因很重要。Fedora 默认配置里用的是官方源,地址长这样:
https://download.fedoraproject.org/pub/fedora/linux/
国内访问这个地址有两个致命问题:
网络延迟和丢包。 数据包要从国内绕道海外,路由跳数多,TCP 握手经常超时。dnf 在下载元数据(repomd.xml)的时候尤其敏感,因为它需要一次性拉取大量的小文件,任何一个超时都会导致整个同步失败。
官方源本身偶尔会清理旧版本。 Fedora 是滚动更新频繁的发行版,每批新版本发布后,旧版本的 RPM 包会逐渐从主仓库移走。如果你的系统版本和源里记录的版本对不上(比如你装的是 Fedora 38 但源指向了 39 的清理路径),就会直接 404。
CDN 缓存问题。 部分运营商的 DNS 解析到了错误的镜像节点,节点本身又没有同步完整,包列表和实际文件对不上,也会出现 404。
知道原因之后,解决思路就清晰了:换源 + 清理缓存 + 修正版本匹配 + 排查依赖。下面一步步来。
第一步:备份现有源配置
很多教程上来就直接删文件,我建议先备份。Fedora 的镜像源配置集中在 /etc/yum.repos.d/ 目录下,里面有几个关键文件:
/etc/yum.repos.d/fedora.repo # 主仓库
/etc/yum.repos.d/fedora-updates.repo # 更新仓库
/etc/yum.repos.d/fedora-modular.repo # 模块化仓库
/etc/yum.repos.d/fedora-source.repo # 源码仓库(一般用不到)
先把它们挪到备份目录:
sudo mkdir -p /etc/yum.repos.d/backup
sudo mv /etc/yum.repos.d/fedora*.repo /etc/yum.repos.d/backup/
这一步看似多余,但万一你后面的操作哪里搞错了,还能恢复原样重新来过。养成这个习惯,后面遇到其他 Linux 发行版也会受益匪浅。
第二步:选择合适的国内镜像源
国内有好几个质量不错的 Fedora 镜像站,我逐个分析一下,你可以根据自己的网络环境挑一个。
阿里云镜像(推荐)
https://mirrors.aliyun.com/fedora/
阿里云的 Fedora 镜像同步速度很快,通常官方更新后 1-2 小时内就能同步完成。带宽充裕,下载体验稳定。缺点是对大文件(比如完整的 ISO)偶尔会限速,但日常装包完全没问题。
清华 TUNA 镜像(稳定首选)
https://mirrors.tuna.tsinghua.edu.cn/fedora/
TUNA 是高校镜像,质量极其稳定,同步策略严谨,不会出现阿里云那种偶尔的延迟。适合对稳定性要求高的场景。缺点是访问高峰期(比如晚上)带宽可能会稍微紧张一点。
中科大 USTC 镜像
https://mirrors.ustc.edu.cn/fedora/
中科大的镜像覆盖面广,南方用户访问速度不错。同步频率也很高,是个靠谱的选择。
华为云镜像
https://mirrors.huaweicloud.com/fedora/
华为云的镜像近年投入很大,网络质量提升明显,西北和华北用户可能体验更好。
网易 163 镜像
http://mirrors.163.com/fedora/
老牌镜像站,但 163 对 Fedora 的维护力度近年有所减弱,同步及时性不如上面几个,不太推荐作为首选。
我建议你优先用阿里云或清华。下面的配置示例以阿里云为例,你可以根据实际情况替换域名。
第三步:创建新的源配置文件
现在用文本编辑器创建新的 repo 文件。用 nano 或 vim 都行,这里我用 nano,因为对新手更友好:
sudo nano /etc/yum.repos.d/fedora.repo
把下面的内容粘贴进去:
[fedora]
name=Fedora $releasever - $basearch
baseurl=https://mirrors.aliyun.com/fedora/releases/$releasever/Everything/$basearch/os/
#mirrorlist=https://mirrors.fedoraproject.org/mirrorlist?repo=fedora-$releasever&arch=$basearch
enabled=1
countme=1
metadata_expire=7d
repo_gpgcheck=0
type=rpm
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/Fedora-RPM-GPG-KEY
skip_if_unavailable=1
[fedora-debuginfo]
name=Fedora $releasever - $basearch - Debug
baseurl=https://mirrors.aliyun.com/fedora/releases/$releasever/Everything/$basearch/debug/
enabled=0
metadata_expire=7d
repo_gpgcheck=0
type=rpm
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/Fedora-RPM-GPG-KEY
skip_if_unavailable=1
[fedora-source]
name=Fedora $releasever - Source
baseurl=https://mirrors.aliyun.com/fedora/releases/$releasever/Everything/source/SRPMS/
enabled=0
metadata_expire=7d
repo_gpgcheck=0
type=rpm
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/Fedora-RPM-GPG-KEY
skip_if_unavailable=1
几个关键参数说明一下:
baseurl直接指定了阿里云的完整路径,绕过了 mirrorlist 的自动选择,避免了解析到错误节点的问题。mirrorlist那一行被注释掉了,如果你有特殊需求可以取消注释。enabled=1开启仓库,enabled=0关闭(debuginfo 和 source 默认关闭,因为平时用不到)。repo_gpgcheck=0关闭仓库级 GPG 检查,加快元数据验证速度。注意这只是跳过了对 repomd.xml 的 GPG 签名验证,实际的 RPM 包还是会用gpgcheck=1验证签名的,安全性有保障。gpgcheck=1确保下载的 RPM 包确实来自 Fedora 官方,防止中间人篡改。skip_if_unavailable=1这个很重要,当源暂时不可用时不会让整个 dnf 命令失败,而是跳过这个源继续尝试其他源。
接着创建更新仓库的配置:
sudo nano /etc/yum.repos.d/fedora-updates.repo
内容如下:
[updates]
name=Fedora $releasever - $basearch - Updates
baseurl=https://mirrors.aliyun.com/fedora/updates/releases/$releasever/Everything/$basearch/os/
#mirrorlist=https://mirrors.fedoraproject.org/mirrorlist?repo=updates-released-f$releasever&arch=$basearch
enabled=1
countme=1
metadata_expire=6h
repo_gpgcheck=0
type=rpm
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/Fedora-RPM-GPG-KEY
skip_if_unavailable=1
[updates-debuginfo]
name=Fedora $releasever - $basearch - Updates - Debug
baseurl=https://mirrors.aliyun.com/fedora/updates/releases/$releasever/Everything/$basearch/debug/
enabled=0
metadata_expire=6h
repo_gpgcheck=0
type=rpm
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/Fedora-RPM-GPG-KEY
skip_if_unavailable=1
[updates-source]
name=Fedora $releasever - $basearch - Updates Source
baseurl=https://mirrors.aliyun.com/fedora/updates/releases/$releasever/Everything/source/SRPMS/
enabled=0
metadata_expire=6h
repo_gpgcheck=0
type=rpm
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/Fedora-RPM-GPG-KEY
skip_if_unavailable=1
这里 metadata_expire=6h 比主仓库的 7 天更短,因为更新仓库变化更频繁,需要更经常地刷新元数据。
如果你用的是清华源,把 baseurl 里的 mirrors.aliyun.com 替换成 mirrors.tuna.tsinghua.edu.cn 就行,路径结构是一样的。
第四步:清理缓存并重新生成元数据
改完配置文件只是第一步,dnf 本地还存着旧的缓存数据,如果不清掉,它可能还会用旧的路径去尝试下载,继续报错。执行以下命令彻底清理:
sudo dnf clean all
这个命令会清除所有缓存的包和元数据,包括:
- 包缓存(
/var/cache/dnf/下的内容) - 元数据缓存
- 插件缓存
- 其他临时文件
清理完之后,强制刷新元数据:
sudo dnf makecache
你会看到终端输出类似这样的信息:
Fedora 39 - x86_64 4.2 MB/s | 95 MB 00:22
Fedora 39 - x86_64 - Updates 3.8 MB/s | 42 MB 00:11
Metadata cache created.
如果这里又报错了,说明你的源路径或者版本号有问题。这时候需要检查一下当前系统的实际版本:
rpm -E %fedora
输出应该是一个数字,比如 39。确保你的 baseurl 里写的 $releasever 能正确展开成这个值。有时候如果你在容器里或者特殊环境下,$releasever 可能无法正确解析,这时候需要手动指定版本号,比如把 $releasever 替换成 39。
第五步:测试安装,验证源是否生效
源配置好之后,先做个小测试,装一个常用的轻量级工具:
sudo dnf install htop -y
如果这个命令成功执行并且没有报错,说明基本的源配置已经没问题了。htop 是个很小的包,依赖也简单,适合作为测试目标。
接下来可以试着更新一下系统:
sudo dnf upgrade --refresh
--refresh 参数强制重新下载所有元数据,确保使用的是最新的包列表。这个过程可能需要几分钟,取决于你的网速和包的数量。
如果更新过程中又出现了 404 错误,不要慌,说明问题可能不在源本身,而在某些特定的包或者依赖关系上。这时候进入下一步。
第六步:解决依赖缺失问题
这是最容易让人头疼的部分。有时候源换好了,但装某个软件时还是会报依赖缺失,比如:
Problem: package xxx-1.0-1.fc39.x86_64 requires yyyy, but none of the providers can be installed
或者:
cannot install the best candidate for the job
这些错误表面上看起来是包找不到,但实际上往往是以下几个原因导致的:
原因一:多个仓库版本冲突
Fedora 有多个仓库层次:base、updates、extras、copr 等。不同仓库可能提供相同但版本不同的包,dnf 在解决依赖时可能会选到错误的版本。
检查一下当前启用的仓库:
dnf repolist all
你会看到类似这样的输出:
repo id repo name status
fedora Fedora 39 - x86_64 enabled
fedora-modular Fedora Modular 39 - x86_64 enabled
updates Fedora 39 - x86_64 - Updates enabled
updates-modular Fedora Modular 39 - x86_64 - Updates enabled
注意 fedora-modular 和 updates-modular 这两个仓库。它们提供模块化版本的包,有时候会和主仓库的包产生冲突。如果你不是专门用模块化的,可以考虑临时禁用它们:
sudo dnf config-manager --set-disabled fedora-modular updates-modular
然后再试一次安装。
原因二:第三方仓库引入了不兼容的包
很多用户会添加 RPM Fusion、CopdRIVER 等第三方仓库。这些仓库本身质量不错,但有时候和官方仓库的包版本对不齐。
查看已添加的第三方仓库:
dnf repolist
如果看到 rpmfusion-free、rpmfusion-nonfree、copr 之类的,就是第三方仓库。如果某个依赖问题只在添加特定仓库后出现,可以尝试临时禁用它们:
sudo dnf config-manager --set-disabled rpmfusion-free rpmfusion-nonfree
然后重新尝试安装。如果成功,说明问题出在第三方仓库和官方仓库的版本冲突上,需要分别更新它们:
sudo dnf update rpmfusion-free-release rpmfusion-nonfree-release
原因三:系统版本和仓库版本不匹配
这是最隐蔽也最容易出错的情况。假设你的系统实际是 Fedora 39,但因为某种原因(比如手动改过配置、从旧版本升级过来没清理干净),dnf 尝试从 Fedora 38 的仓库拉包,或者反过来,就会大量 404。
检查系统的实际版本和仓库的版本是否一致:
cat /etc/fedora-release
dnf repoinfo
如果发现有版本不一致,可以先尝试强制更新 release 包:
sudo dnf upgrade fedora-release
然后重新同步:
sudo dnf clean all
sudo dnf makecache --refresh
原因四:依赖解析算法本身的问题
偶尔 dnf 的依赖解析会抽风,明明包存在却报找不到。这时候可以强制刷新依赖缓存:
sudo dnf distro-sync
distro-sync 会把你系统上所有已安装的包和仓库中的最新版本对齐,解决很多隐性的依赖问题。执行前最好先确认一下它要做的变更,因为可能会升级或降级一些包:
sudo dnf distro-sync --assumeno
--assumeno 参数会让 dnf 只列出要做的操作而不实际执行,先过一遍看有没有什么不合理的变更。确认没问题后去掉这个参数正式执行。
第七步:处理特殊的 404 场景
有些 404 错误比较特殊,需要针对性处理。
场景一:某个特定包 404
如果你装某个特定软件时 404,但其他软件正常,可能是那个包在镜像站确实没有同步过去。可以检查一下:
dnf --nogpgcheck list available | grep 包名
如果查不到,说明这个包在镜像源里确实不存在。这时候有两个选择:
- 等镜像站同步(通常几小时内会跟上)
- 切换到其他镜像源试试
场景二:升级系统后大量 404
从旧版本升级到新版本后,经常会出现大量 404,因为旧版本的缓存还在,但新版本的包路径已经完全变了。处理方法是彻底清理并重做:
sudo dnf clean all
sudo rm -rf /var/cache/dnf
sudo dnf makecache
注意 rm -rf 这个命令比较危险,确保路径是对的。/var/cache/dnf 是 dnf 的缓存目录,删掉后 dnf 会自动重建。
场景三:使用 Copr 仓库时 404
Copr 是 Fedora 的第三方包构建平台,很多用户会用它来安装不在官方仓库里的软件。Copr 的仓库结构比较特殊,有时候构建失败或者包被删除后,元数据里还残留着引用,导致 404。
检查 Cpr 相关的错误:
sudo dnf copr list
对于不再需要的 Cpr 仓库,可以直接禁用或删除:
sudo dnf copr remove 用户名/项目名
场景四:模块化仓库的问题
Fedora 引入了模块化的概念,一些软件(比如 Python、Node.js、数据库)以模块的形式提供。模块的流(stream)和版本管理比较严格,有时候切换流会导致依赖问题。
查看当前模块状态:
dnf module list
如果某个模块有问题,可以尝试重置:
sudo dnf module reset 模块名
第八步:自动化检查和修复脚本
如果你经常遇到这类问题,可以把一些常用的排查命令封装成一个脚本,方便以后一键修复:
#!/bin/bash
# Fedora 源问题自动检查和修复脚本
echo "=== 检查系统版本 ==="
echo "Fedora 版本: $(rpm -E %fedora)"
echo "架构: $(uname -m)"
echo ""
echo "=== 检查启用的仓库 ==="
dnf repolist enabled
echo ""
echo "=== 清理缓存 ==="
sudo dnf clean all
sudo rm -rf /var/cache/dnf
echo ""
echo "=== 重新生成元数据 ==="
sudo dnf makecache --refresh
echo ""
echo "=== 检查是否有待处理的更新 ==="
sudo dnf check-update
echo ""
echo "=== 检查依赖完整性 ==="
sudo dnf distro-sync --assumeno
echo ""
echo "=== 修复完成 ==="
echo "请尝试重新安装您需要的软件"
把这个脚本保存为 fix-fedora-dnf.sh,加上执行权限:
chmod +x fix-fedora-dnf.sh
以后遇到问题直接运行:
./fix-fedora-dnf.sh
第九步:一些实用的排查技巧
最后分享几个我在折腾过程中积累的实用技巧,很多时候能快速定位问题。
技巧一:开启 dnf 的详细日志
当 404 错误莫名其妙时,加上 -v 或 -vv 参数可以输出详细的调试信息:
sudo dnf -v install 包名
或者设置永久调试模式,在 /etc/dnf/dnf.conf 里加一行:
debuglevel=5
debuglevel 从 0 到 10,5 是比较适合日常调试的值,会输出足够的信息但不会太啰嗦。
技巧二:手动测试单个包的下载
有时候 dnf 报 404 但实际可能是网络问题。你可以直接用 curl 测试某个包是否真的能下载:
curl -I https://mirrors.aliyun.com/fedora/releases/39/Everything/x86_64/os/Packages/l/lttng-ust-2.13.0-1.fc39.x86_64.rpm
如果 curl 返回 HTTP/2 404,说明这个包在镜像源里确实不存在;如果返回 HTTP/2 200,说明包是存在的,问题在 dnf 的配置或缓存上。
技巧三:查看 dnf 的历史记录
如果不确定最近改了什么导致了问题,可以查看 dnf 的交易历史:
sudo dnf history list
找到最近的几条记录,用 info 查看详细信息:
sudo dnf history info 编号
有时候问题可能是之前某次不完整的更新留下的后遗症。
技巧四:使用 --skip-broken 参数
如果依赖问题实在复杂,可以先用 --skip-broken 跳过有问题的包,把能装的先装上:
sudo dnf install 包名 --skip-broken
这不会解决根本问题,但可以作为一个临时的 workaround,让你在不完全阻塞的情况下继续工作。
技巧五:切换回官方源作为最后的验证手段
如果换了所有国内镜像还是有 404,可以用官方源做一次对比测试。临时创建一个只包含官方源的配置,看看问题是否复现。如果官方源正常,说明是国内镜像的同步问题;如果官方源也有问题,说明是你的系统配置或者网络环境问题。
一些常见问题的快速对照表
为了方便你快速定位,我把上面提到的各种情况和对应的解决方案整理成一张表:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 所有包都 404 | 镜像源路径错误或版本不匹配 | 检查 releasever,重新配置 baseurl |
| 部分包 404 | 镜像同步延迟 | 等待或切换其他镜像 |
| 特定仓库 404 | 该仓库的元数据损坏 | dnf clean all 并重新 makecache |
| 依赖缺失 | 模块流冲突或多仓库版本冲突 | 检查 dnf module list,禁用 modular 仓库 |
| 升级后大量 404 | 缓存残留旧路径 | 彻底清理 /var/cache/dnf |
| Copr 仓库 404 | 包被删除或构建失败 | dnf copr remove 移除问题仓库 |
| 网络超时导致 404 | DNS 解析到错误节点 | 使用 baseurl 直接指定,禁用 mirrorlist |
说实话,Fedora 在国内的生态确实不如 Ubuntu 或者 Deepin 那么友好,源的问题也是老生常谈了。但一旦你把镜像源配置好、把依赖关系理顺,后续的体验其实是非常流畅的。Fedora 的包质量高、更新快、系统干净,用来做开发环境或者日常桌面都非常合适。
希望这篇指南能帮你解决遇到的问题。如果还有什么不清楚的,或者遇到了我没覆盖到的特殊情况,随时可以再来问。折腾 Linux 就是这样,遇到问题、解决问题、积累经验,每一步都是在变得更熟练。
