Skip to content

Pubsub UND_ERR_BODY_TIMEOUT in Docker: undici 7→8 global-dispatcher symbol split #84

@Rinse12

Description

@Rinse12

Summary

The daemon (Docker / this branch) logs recurring pubsub errors:

pkc-js:...:pubsubSubscribeOnProvider:error pubsub callback error ... TypeError: terminated
[cause]: BodyTimeoutError: Body Timeout Error (UND_ERR_BODY_TIMEOUT)
  at .../@libp2p/http/node_modules/undici/lib/dispatcher/client-h1.js

It does not reproduce when running the published CLI via a host npm install.

Root cause (verified empirically)

An idle long-poll HTTP stream is aborted by undici's default 5-minute bodyTimeout. pkc-js
ships a polyfill that disables this:

// pkc-js/dist/node/runtime/node/polyfill.js
setGlobalDispatcher(new Agent({ bodyTimeout: Number.MAX_SAFE_INTEGER }))

But undici changed its global-dispatcher symbol between v7 and v8:

undici get/setGlobalDispatcher slot
7.x Symbol.for('undici.globalDispatcher.1')
8.x Symbol.for('undici.globalDispatcher.2') (.1 legacy only)

setGlobalDispatcher writes the slot of whichever undici is hoisted to top-level:

  • This branch / Docker: top-level undici is 7.25.0 (hoisted for open-graph-scraper@^7
    • cheerio@^7); @libp2p/http@^8.0.3 is nested on its own undici 8.x. pkc writes .1;
      the helia / @libp2p/http request reads .2 (never set) → default 300s → timeout.
  • Host install: top-level undici is 8.x; pkc writes .2; the @libp2p/http request
    reads .2 = pkc's MAX-bodyTimeout agent → no timeout.

The kubo-rpc-client pubsub long-poll itself uses native global fetch (reads .1) and is
covered by the polyfill; the timing-out request is the undici-8.x / @libp2p/http (helia) path.

Fix

Hoist undici 8.x to top-level (mirroring the working host layout) so pkc's polyfill writes the
.2 slot that the @libp2p/http path reads — add a direct undici@^8 dependency; ^7
consumers (cheerio, open-graph-scraper) keep their own nested 7.x copies.

Likely surfaced by the kubo 0.41→0.42 dependency bump on this branch re-hoisting undici to 7.x.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions