Skip to content

fix(bootstrap): skip backup peer list when no bootstrap peers configured - #1213

Merged
lidel merged 2 commits into
ipfs:mainfrom
karawitan:fix/bootstrap-skip-backup-when-no-peers
Sep 7, 2026
Merged

fix(bootstrap): skip backup peer list when no bootstrap peers configured#1213
lidel merged 2 commits into
ipfs:mainfrom
karawitan:fix/bootstrap-skip-backup-when-no-peers

Conversation

@karawitan

@karawitan karawitan commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Problem

When a node has no bootstrap peers configured (for example Routing.Type=none with an empty Bootstrap list, or ipfs daemon --routing=none), bootstrapRound still loads and dials backup peers persisted from previous runs (stored under TempBootstrapPeersKey in the datastore). This causes unwanted external DNS resolution and connection attempts to stale addresses every 30 seconds, even though the operator explicitly disabled routing/bootstrap. Reported in kubo#11452.

The backup peer list exists as a recovery mechanism for when configured bootstrap peers are down (#8856). With no configured bootstrap peers, there is nothing to recover from, so consulting the backup list is the wrong behavior.

Fix

In bootstrapRound, return early when cfg.BootstrapPeers() returns an empty list, before consulting the backup peer list. This:

  • Covers Bootstrap: null / empty list (becomes an empty []peer.AddrInfo)
  • Works with ipfs daemon --routing=none (runtime override that does not change the config file)
  • Keeps Routing.Type=none + explicit Bootstrap peers working (those nodes still dial their configured peers)
  • Needs no new config option

Nodes that configure explicit Bootstrap peers are unaffected: the backup-list fallback still runs when those peers fail to connect.

Behavior change

Previously, a node with default routing and an empty Bootstrap list would still dial backup peers. After this change it does not. This aligns behavior with operator intent: an empty Bootstrap list now means "no bootstrap dialing at all, including saved backup peers." This is a fix, directed by @lidel in kubo#11453 (review): "The simplest fix is in boxo, in bootstrap.bootstrapRound: when cfg.BootstrapPeers() returns nothing, stop there instead of trying the backup list."

Testing

  • go build ./bootstrap/... passes
  • go test ./bootstrap/... -count=1 passes (all existing tests green)
  • go vet ./bootstrap/... passes
  • gofmt -l bootstrap/ clean
  • Added TestBootstrapRoundSkipsBackupWhenNoBootstrapPeers: verifies bootstrapRound does not call loadBackupBootstrapPeers when BootstrapPeers() is empty
  • Added TestBootstrapRoundDialsBackupWhenBootstrapPeersPresent: verifies the backup list is still consulted when configured bootstrap peers fail to connect, preserving the #8856 recovery mechanism

Companion kubo PR

REQUIRED companion kubo PR: ipfs/kubo#11453 (reworked to pin this boxo branch, fix docs, and add a kubo-level regression test). It is a draft while this boxo PR is unmerged; kubo CI status will be reported there.

Generated with Devin

@karawitan
karawitan requested a review from a team as a code owner September 7, 2026 07:12
bootstrapRound no longer consults the backup peer list when
cfg.BootstrapPeers() returns empty. The backup list exists only as a
recovery mechanism for when configured bootstrap peers are down
(#8856); with no configured peers there is nothing to recover from,
so dialing stale backup peers persisted from previous runs is
skipped.

This lets a caller fully disable bootstrap dialing by setting an
empty peer list (for example a local-only/offline node with
Routing.Type=none), and works with runtime overrides such as
`ipfs daemon --routing=none` that do not change the config file.
Nodes that configure explicit Bootstrap peers are unaffected.

Closes kubo issue #11452 (companion kubo PR to follow).

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@karawitan
karawitan force-pushed the fix/bootstrap-skip-backup-when-no-peers branch from fc791c5 to 76cf61a Compare September 7, 2026 07:12
karawitan pushed a commit to karawitan/kubo that referenced this pull request Sep 7, 2026
Rework of ipfs#11453 per maintainer review (lidel): the fix belongs in
boxo (bootstrap.bootstrapRound skips the backup list when no
bootstrap peers are configured), not behind a Routing.Type=none guard
in kubo. This PR is now the companion to ipfs/boxo#1213:

- Pin the boxo fix via a temporary replace directive pointing at the
  boxo PR branch. Once ipfs/boxo#1213 merges, repoint at boxo main
  and convert to a pseudo-version pin.
- Add a kubo-level regression test
  (TestBootstrapWithEmptyPeerListAndStaleBackupPeers) verifying
  IpfsNode.Bootstrap runs with an empty Bootstrap config and a
  populated TempBootstrapPeersKey without error.
- Document under Bootstrap in docs/config.md that an empty list
  disables all bootstrap dialing, including saved backup peers.
- Add a v0.44 changelog highlight. Drop the v0.43 entry and the
  broken emoji from the original PR.

Closes ipfs#11452

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Shorten the empty-list comment and the changelog entry, point the
#8856 and #11452 references at ipfs/kubo, drop the unused peerID in
the new tests and use t.Context().

@lidel lidel left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for moving this over so quickly.

Pushed df6852a on top: shorter code comment and changelog entry, references to ipfs/kubo#8856 and ipfs/kubo#11452 now carry the repo (bare numbers resolve to unrelated boxo items here), and the tests drop the unused peerID and use t.Context().

The Devin-generated prose was a bit generous with words for a small fix, so I trimmed it; a quick pass over its output before posting saves reviewers time. The PR description still links ipfs/boxo/pull/8856 where ipfs/kubo#8856 is meant, if you want to fix that.

Otherwise LGTM.

@lidel
lidel merged commit 2edf737 into ipfs:main Sep 7, 2026
21 checks passed
lidel added a commit to karawitan/kubo that referenced this pull request Sep 7, 2026
Drops the temporary replace on a fork now that ipfs/boxo#1213 is
merged, and moves the changelog entry to v0.43.1.
lidel added a commit to ipfs/kubo that referenced this pull request Sep 7, 2026
* fix: empty Bootstrap list no longer dials stale backup peers

Rework of #11453 per maintainer review (lidel): the fix belongs in
boxo (bootstrap.bootstrapRound skips the backup list when no
bootstrap peers are configured), not behind a Routing.Type=none guard
in kubo. This PR is now the companion to ipfs/boxo#1213:

- Pin the boxo fix via a temporary replace directive pointing at the
  boxo PR branch. Once ipfs/boxo#1213 merges, repoint at boxo main
  and convert to a pseudo-version pin.
- Add a kubo-level regression test
  (TestBootstrapWithEmptyPeerListAndStaleBackupPeers) verifying
  IpfsNode.Bootstrap runs with an empty Bootstrap config and a
  populated TempBootstrapPeersKey without error.
- Document under Bootstrap in docs/config.md that an empty list
  disables all bootstrap dialing, including saved backup peers.
- Add a v0.44 changelog highlight. Drop the v0.43 entry and the
  broken emoji from the original PR.

Closes #11452

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore: review follow-ups for empty Bootstrap list

Replace the kubo-level test with one that fails without the boxo fix
(a mocknet backup peer must not be dialed when Bootstrap is empty),
shorten the changelog and config.md text, and point the boxo replace
at the reviewed commit.

* test: bootstrap fallback needs a configured peer

TestBackupBootstrapPeers used an empty Bootstrap list to force the
fallback to saved peers. An empty list now disables bootstrap dialing
entirely, so the test configures an unreachable bootstrap peer instead.
The changelog and config.md describe what still connects with an
empty list and when backup peers are used.

* chore: update boxo to 2edf737db3aa

Drops the temporary replace on a fork now that ipfs/boxo#1213 is
merged, and moves the changelog entry to v0.43.1.

---------

Co-authored-by: kalou <research@beleganjur.kalou.net>
Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Marcin Rataj <lidel@lidel.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants