# rpm命令报错"error: Failed to initialize NSS library"

在使用rpm命令时提示错误"error: Failed to initialize NSS library":

```
$ rpm -qa
error: Failed to initialize NSS library
```

这个问题通过google搜索能够找不少解决方法，大多数都是围绕libnspr4库文件，如[Linux : Yum/rpm broken upgrading from CentOS/RHEL 7.3 to 7.4 (error: Failed to initialize NSS library)](https://www.itechlounge.net/2017/09/linux-yumrpm-broken-upgrading-from-centosrhel-7-3-to-7-4-error-failed-to-initialize-nss-library/)介绍；或者如[Bug 1476031 - Failed to initialize NSS library](https://bugzilla.redhat.com/show_bug.cgi?id=1476031)说明的，由于`nss-softokn-freebl`升级但是`nspr`没有升级，一般解决的方法是通过将rpm包下载（例如回滚到原有版本）以后，在通过`rpm2cpio`解压缩，手工复制修复。

不过，也有可能是由于其他库文件损坏导致，此时虽然看上去是NSS库初始化失败，但是实际上需要修复其他库文件。

检查的方法是采用`strace`，这个工具提供了`-eopen`参数来跟踪执行命令所使用的文件。注意：有些和语言相关的`xxx.mo`文件虽然不存在但是也不影响运行（对比正常服务器）。

不过，即使文件完全准确存在也可能出现异常，所以通过`strace rpm`命令检查完整的库文件调用顺序，查看出现异常是哪个文件：

```
strace rpm
```

显示错误最后调用的库文件是`/lib64/libfreeblpriv3.so`

```
...
open("/lib64/libfreeblpriv3.so", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\0;\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=526912, ...}) = 0
mmap(NULL, 2631448, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7f206e6000
mprotect(0x7f7f20763000, 2093056, PROT_NONE) = 0
mmap(0x7f7f20962000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x7c000) = 0x7f7f20962000
mmap(0x7f7f20965000, 14104, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7f20965000
close(3)                                = 0
mprotect(0x7f7f20962000, 8192, PROT_READ) = 0
munmap(0x7f7f2afa6000, 35038)           = 0
munmap(0x7f7f206e6000, 2631448)         = 0
open("/proc/sys/crypto/fips_enabled", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7f2afbd000
read(3, "0\n", 1024)                    = 2
close(3)                                = 0
munmap(0x7f7f2afbd000, 4096)            = 0
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2502, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7f2afbd000
read(3, "# Locale name alias data base.\n#"..., 4096) = 2502
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0x7f7f2afbd000, 4096)            = 0
open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/rpm.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US.utf8/LC_MESSAGES/rpm.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en_US/LC_MESSAGES/rpm.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.UTF-8/LC_MESSAGES/rpm.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en.utf8/LC_MESSAGES/rpm.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/en/LC_MESSAGES/rpm.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
write(2, "error: ", 7error: )                  = 7
write(2, "Failed to initialize NSS library"..., 33Failed to initialize NSS library
) = 33
exit_group(1)                           = ?
+++ exited with 1 +++
```

检查对比发现，异常的`/lib64/libfreeblpriv3.so`文件时间戳

```
$ls -lh /lib64/libfreeblpriv3.so
-rwxr-xr-x 1 root root 515K Sep 15  2017 /lib64/libfreeblpriv3.so
```

而正常的服务器上这个时间戳比较早

```
$ls -lh /lib64/libfreeblpriv3.so
-rwxr-xr-x 1 root root 503K Dec 14  2015 /lib64/libfreeblpriv3.so
```

所以在正常服务器上检查这个文件属于哪个rpm包

```
$rpm -qf /lib64/libfreeblpriv3.so
nss-softokn-freebl-3.16.2.3-13.1.alios7.x86_64
```

然后手工下载rpm并解压缩后修复：

```
rpm2cpio nss-softokn-freebl-3.16.2.3-13.1.alios7.x86_64.rpm |cpio -imdv
cp usr/lib64/* /lib64/
```

## 参考

* [Bug 1353159 - dnf and rpm stopped working with error 'Failed to initialize NSS library' after updating](https://bugzilla.redhat.com/show_bug.cgi?id=1353159)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://huataihuang.gitbook.io/cloud-atlas-draft/os/linux/redhat/package/rpm_fail_initialize_nss_library.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
