fix(libp2p): drop empty addrs in AddrsFactory (#11302)
A zero-value Multiaddr (since go-multiaddr v0.15 is a slice type) encodes to zero bytes on the wire. AddrsFactory was passing such empty entries through to the host's signed peer record, where peers that skip the empty-input check render them as "/" and reject the address. js-libp2p autonatv2 first flagged this against a kubo/0.39.0/2896aed/docker agent. AddrsFactory is the central chokepoint for kubo's announced addresses, so filtering here scrubs every downstream consumer until the upstream go-libp2p fix lands. See https://github.com/libp2p/js-libp2p/issues/3478#issuecomment-4322093929
Marcin Rataj committed
Apr 30, 2026 at 00:09 UTC
e931b379e7dc9a74d62e005097e7b9601484b5dc
2 files changed
+45
core/node/libp2p/addrs.go
+8
@@ -88,6 +88,14 @@ func makeAddrsFactory(announce []string, appendAnnounce []string, noAnnounce []s
88
89
var out []ma.Multiaddr
90
for _, maddr := range addrs {
91
+ // Drop empty multiaddrs. Since go-multiaddr v0.15 made
92
+ // Multiaddr a slice type, a zero-value Multiaddr encodes to
93
+ // zero bytes and would otherwise reach the host's signed peer
94
+ // record, where peers render it as "/" and reject the address.
95
+ // See https://github.com/libp2p/js-libp2p/issues/3478#issuecomment-4322093929
96
+ if len(maddr) == 0 {
97
+ continue
98
+ }
99
// check for exact matches
100
ok := noAnnAddrs[string(maddr.Bytes())]
101
// check for /ipcidr matches
core/node/libp2p/addrs_test.go
new
+37
@@ -0,0 +1,37 @@
1
+package libp2p
2
+
3
+import (
4
+ "testing"
5
+
6
+ ma "github.com/multiformats/go-multiaddr"
7
+)
8
+
9
+// makeAddrsFactory must drop empty multiaddrs from the input list.
10
+// A zero-component Multiaddr would otherwise reach the host's signed
11
+// peer record and propagate to peers as "/" when they decode the wire
12
+// bytes.
13
+//
14
+// See https://github.com/libp2p/js-libp2p/issues/3478#issuecomment-4322093929
15
+func TestMakeAddrsFactoryDropsEmptyMultiaddrs(t *testing.T) {
16
+ factory, err := makeAddrsFactory(nil, nil, nil)
17
+ if err != nil {
18
+ t.Fatal(err)
19
+ }
20
+
21
+ good, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/4001")
22
+ if err != nil {
23
+ t.Fatal(err)
24
+ }
25
+
26
+ in := []ma.Multiaddr{nil, good, {}, good}
27
+ out := factory(in)
28
+
29
+ if len(out) != 2 {
30
+ t.Fatalf("expected 2 addrs after factory filter, got %d: %v", len(out), out)
31
+ }
32
+ for i, a := range out {
33
+ if len(a) == 0 {
34
+ t.Fatalf("factory returned an empty multiaddr at index %d", i)
35
+ }
36
+ }
37
+}