| Tested on | RHEL 10.2 |
|---|---|
| Package | sysctl (procps-ng) |
| Applies to | RHEL, Rocky Linux, AlmaLinux, CentOS Stream, Fedora, Ubuntu, Debian, and other Linux systems with IPv6 and net.ipv6.conf.*.stable_secret |
| Privilege | Normal user to read most keys; root to read stable_secret procfs nodes |
| Scope | Explain sysctl: reading key "net.ipv6.conf.*.stable_secret" when filtering sysctl -a, suppress stderr noise in scripts, and read specific IPv6 keys without a full dump. Does not cover full IPv6 disable or performance tuning. |
| Related guides | sysctl command grep command Linux disable IPv6 properly sysctl for high-performance servers |
You ran sysctl -a | grep something and stderr filled with lines like
sysctl: reading key "net.ipv6.conf.all.stable_secret". The grep output
you wanted may still be on stdout, but the extra noise makes scripts and
log reviews harder. This page explains what that message means and how
to filter sysctl output without mistaking it for a broken network stack.
What the stable_secret Message Means
net.ipv6.conf.*.stable_secret is a legitimate kernel tunable. It holds
the secret used for stable privacy IPv6 address generation (RFC 7217).
By default the secret is unset. The kernel documents the key under
ip-sysctl.txt;
it is not a sign that IPv6 is misconfigured.
On older kernel and procps combinations, listing every parameter with
sysctl -a can still attempt to read stable_secret for each
interface. When the secret is unset, that read fails and procps prints a
diagnostic line to stderr for each path.
When sysctl -a walks every tunable, grepping rp_filter can still
surface stable_secret warnings on stderr:
sysctl -a | grep rp_filter[root@master ~]# sysctl -a | grep rp_filter
net.ipv4.conf.all.arp_filter = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.arp_filter = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.eth0.arp_filter = 0
net.ipv4.conf.eth0.rp_filter = 1
net.ipv4.conf.lo.arp_filter = 0
net.ipv4.conf.lo.rp_filter = 0
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.eth0.stable_secret"
sysctl: reading key "net.ipv6.conf.eth1.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0-nic.stable_secret"The rp_filter lines on stdout are fine. The stable_secret lines are
procps complaining while it walks parameters you did not ask for.
Why stable_secret Can Return an I/O Error
The kernel documents stable_secret in ip-sysctl.txt:
stable_secret - IPv6 address
This IPv6 address will be used as a secret to generate IPv6
addresses for link-local addresses and autoconfigured
ones. All addresses generated after setting this secret will
be stable privacy ones by default. This can be changed via the
addrgenmode ip-link. conf/default/stable_secret is used as the
secret for the namespace, the interface specific ones can
overwrite that. Writes to conf/all/stable_secret are refused.
It is recommended to generate this secret during installation
of a system and keep it stable after that.
By default the stable secret is unset.When the secret is unset, reading the procfs node directly fails with an
I/O error — the same failure sysctl -a surfaces as a stderr warning
on stacks that still attempt the read:
cat /proc/sys/net/ipv6/conf/all/stable_secret$ cat /proc/sys/net/ipv6/conf/all/stable_secret
cat: /proc/sys/net/ipv6/conf/all/stable_secret: Input/output errorThat is expected for an unreadable privacy secret, not proof that IPv6
must be turned off. Current procps releases also skip some parameters
during sysctl -a that should not be read; you may see this warning less
often on newer systems.
Suppress the Message When Filtering sysctl Output
Redirect stderr when you only care about stdout from grep. That is
what removes the stable_secret noise in practice. Pair --ignore with
2>/dev/null so grep sees only stdout:
sysctl -a --ignore 2>/dev/null | grep rp_filter[root@master ~]# sysctl -a --ignore 2>/dev/null | grep rp_filter
net.ipv4.conf.all.arp_filter = 0
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.arp_filter = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.eth0.arp_filter = 0
net.ipv4.conf.eth0.rp_filter = 1
net.ipv4.conf.lo.arp_filter = 0
net.ipv4.conf.lo.rp_filter = 0The same stderr redirect works with bash |&:
sysctl -a --ignore |& grep rp_filterOr merge stderr into stdout explicitly before grep:
sysctl -a --ignore 2>&1 | grep rp_filtersysctl -e / --ignore tells procps to ignore unknown keys when
loading a file or listing parameters. It is not a general “hide all
errors” switch. The stable_secret keys exist; the read fails with I/O
error. Redirecting stderr (2>/dev/null, |&, or 2>&1 |) is what
actually hides those diagnostic lines while grep keeps matching stdout.
Replace rp_filter with any pattern you need — see grep scenarios for regex ideas.
Grepping IPv6 disable flags can trigger the same stable_secret warnings
until stderr is redirected:
sysctl -a | grep ipv6.*disable[root@master ~]# sysctl -a | grep ipv6.*disable
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.eth0.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.eth0.disable_ipv6 = 0
net.ipv6.conf.eth1.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
net.ipv6.conf.virbr0.disable_ipv6 = 1
net.ipv6.conf.virbr0-nic.disable_ipv6 = 0Use sysctl -a 2>/dev/null | grep 'ipv6.*disable' when you want only the
disable_ipv6 lines.
Check the Setting Without Running sysctl -a
Avoid sysctl -a when you already know the key name. Query one parameter
or a small pattern instead:
sysctl net.ipv6.conf.all.disable_ipv6To list every interface's disable_ipv6 value without a full dump:
sysctl -ar 'net\.ipv6\.conf\..*\.disable_ipv6'That skips the full dump that triggers stable_secret read attempts on
older stacks. For a single forwarding or filter knob, sysctl -n net.ipv4.conf.all.rp_filter keeps scripts quiet for the same reason.
Do not use cat on stable_secret paths unless you intend to configure
stable privacy addressing — an unset secret returns I/O error by design.
Should You Set or Disable IPv6 stable_secret?
| Question | Guidance |
|---|---|
| Should I disable IPv6 to silence this warning? | No. Disabling IPv6 is unrelated to an unset privacy secret and can break dual-stack apps. |
Should I set stable_secret manually? |
Only when you deliberately want stable privacy IPv6 per RFC 7217. Distros that need it generate the secret at install time. |
| Should I panic about the stderr lines? | No if stdout shows the values you grepped for. Redirect stderr in scripts or query named keys instead of sysctl -a. |
If you must reduce IPv6 exposure for policy reasons, follow a dedicated
IPv6 disable procedure — not as a shortcut to clean up sysctl grep output.
Summary
The message sysctl: reading key "net.ipv6.conf.*.stable_secret" appears
when sysctl -a tries to read IPv6 stable-privacy secrets that are unset
by default. Stdout from your grep can still be correct; procps prints the
complaint on stderr.
Redirect stderr when filtering (sysctl -a 2>/dev/null | grep pattern), or
query specific keys with sysctl name / sysctl -ar instead of dumping
everything. sysctl --ignore skips unknown keys only — it does not hide
I/O errors on existing tunables.
Disabling IPv6 is not the right fix for this warning. Treat it as noisy diagnostics on older kernel and procps pairs, and tighten how you read sysctl output in scripts.

