ipfs/kubo · critical
invalid configuration: Bitswap.Libp2pEnabled and HTTPRetriev
Error message
invalid configuration: Bitswap.Libp2pEnabled and HTTPRetrieval.Enabled are both disabled, unable to initialize Bitswap
What it means
Kubo's Bitswap client requires at least one transport network to retrieve blocks: the libp2p bitswap network and/or the HTTP retrieval network. During node construction (fx dependency injection in core/node/bitswap.go), if both Bitswap.Libp2pEnabled and HTTPRetrieval.Enabled are disabled, there is no way to build the bitswap network stack and the constructor fails, aborting daemon startup.
Source
Thrown at core/node/bitswap.go:125
httpCfg.Allowlist != nil,
httpCfg.Denylist != nil,
)
bitswapHTTP := httpnet.New(in.Host,
httpnet.WithHTTPWorkers(int(httpCfg.NumWorkers.WithDefault(config.DefaultHTTPRetrievalNumWorkers))),
httpnet.WithAllowlist(httpCfg.Allowlist),
httpnet.WithDenylist(httpCfg.Denylist),
httpnet.WithInsecureSkipVerify(httpCfg.TLSInsecureSkipVerify.WithDefault(config.DefaultHTTPRetrievalTLSInsecureSkipVerify)),
httpnet.WithMaxBlockSize(int64(maxBlockSize)),
httpnet.WithUserAgent(version.GetUserAgentVersion()),
httpnet.WithMetricsLabelsForEndpoints(httpCfg.Allowlist),
httpnet.WithConnectEventManager(connEvtMgr),
)
bitswapNetworks = network.New(in.Host.Peerstore(), bitswapLibp2p, bitswapHTTP)
} else if libp2pEnabled {
bitswapNetworks = bitswapLibp2p
} else {
return nil, errors.New("invalid configuration: Bitswap.Libp2pEnabled and HTTPRetrieval.Enabled are both disabled, unable to initialize Bitswap")
}
// Kubo uses own, customized ProviderQueryManager
in.BitswapOpts = append(in.BitswapOpts, bitswap.WithClientOption(client.WithDefaultProviderQueryManager(false)))
var maxProviders int = DefaultMaxProviders
var bcDisposition string
if in.Cfg.Internal.Bitswap != nil {
maxProviders = int(in.Cfg.Internal.Bitswap.ProviderSearchMaxResults.WithDefault(DefaultMaxProviders))
if in.Cfg.Internal.Bitswap.BroadcastControl != nil {
bcCfg := in.Cfg.Internal.Bitswap.BroadcastControl
bcEnable := bcCfg.Enable.WithDefault(config.DefaultBroadcastControlEnable)
in.BitswapOpts = append(in.BitswapOpts, bitswap.WithClientOption(client.BroadcastControlEnable(bcEnable)))
if bcEnable {
bcDisposition = "enabled"
bcMaxPeers := int(bcCfg.MaxPeers.WithDefault(config.DefaultBroadcastControlMaxPeers))
in.BitswapOpts = append(in.BitswapOpts, bitswap.WithClientOption(client.BroadcastControlMaxPeers(bcMaxPeers)))
View on GitHub (pinned to 329838acdf)
Solutions
- Re-enable at least one retrieval transport: `ipfs config --json Bitswap.Libp2pEnabled true` (the default) or `ipfs config --json HTTPRetrieval.Enabled true`.
- If you only want HTTP retrieval, keep Libp2pEnabled=false but set HTTPRetrieval.Enabled=true with an Allowlist in HTTPRetrieval config.
- If you meant to disable serving blocks only, use `ipfs config --json Bitswap.ServerEnabled false` instead of disabling the client transports.
- Review the effective config with `ipfs config Bitswap` and `ipfs config HTTPRetrieval` before restarting the daemon.
Example fix
// before (config.json)
{"Bitswap": {"Libp2pEnabled": false}, "HTTPRetrieval": {"Enabled": false}}
// after
{"Bitswap": {"Libp2pEnabled": false}, "HTTPRetrieval": {"Enabled": true, "Allowlists": {"Allowlist": ["example.com"]}}} Defensive patterns
Strategy: validation
Validate before calling
// Before starting the daemon, verify at least one bitswap transport is enabled
import "github.com/ipfs/kubo/config"
cfg, err := repo.Config()
if err != nil { return err }
libp2p := cfg.Bitswap.Libp2pEnabled.WithDefault(config.DefaultBitswapLibp2pEnabled)
http := cfg.HTTPRetrieval.Enabled.WithDefault(config.DefaultHTTPRetrievalEnabled)
if !libp2p && !http {
return fmt.Errorf("at least one of Bitswap.Libp2pEnabled or HTTPRetrieval.Enabled must be true")
} Prevention
- Never disable both Bitswap.Libp2pEnabled and HTTPRetrieval.Enabled; Bitswap.ServerEnabled=false is the correct way to stop serving blocks.
- After scripted config changes, run `ipfs config Bitswap` and `ipfs config HTTPRetrieval` to sanity-check before restart.
- Test config changes on a throwaway IPFS_PATH (`IPFS_PATH=$(mktemp -d) ipfs daemon`) before applying to production.
When it happens
Trigger: Starting `ipfs daemon` with a config where `Bitswap.Libp2pEnabled=false` (or its default-resolved value) and `HTTPRetrieval.Enabled=false` are both set; the Bitswap fx constructor hits the else branch and returns this error before any bitswap client is created.
Common situations: Operators who disable libp2p bitswap (e.g. wanting HTTP-only retrieval) then also turn off HTTPRetrieval believing it is unused; scripted config hardening that zeroes out all retrieval transports; misreading Bitswap.ServerEnabled (server off is fine) as also disabling the client.
Related errors
- private networking (swarm.key / LIBP2P_FORCE_PNET) does not
- Routing.AcceleratedDHTClient option is set even tho Routing.
- serveHTTPApi: GetConfig() failed: %s
- serveHTTPApi: invalid API address: %q (err: %s)
- serveHTTPGateway: GetConfig() failed: %s
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/011f50bb33866b73.
Report an issue: GitHub.