Troubleshooting
One entry per symptom, quoted the way the browser or the library reports it, so a search for the message lands here. Each entry gives the cause and the fix; the reasoning is on the page it links to.
Failed to fetch on an upload through the public gateway
Section titled “Failed to fetch on an upload through the public gateway”Cause. A request header outside the gateway’s short CORS allow-list — Swarm-Pin, Swarm-Tag
or the ACT headers. The browser refuses the request at the preflight and reports nothing more
specific. Through the library it is a SwarmIdError with code network.
Fix. Through Swarm ID this does not happen: the subsidised path sends none of those headers
whatever the upload options say — pin: true is dropped there. If you see it, the request is
your own, bee-js or fetch against the gateway, so drop the pin, tag and ACT options on that
call. See The Public Gateway.
Request timeout after 30000ms
Section titled “Request timeout after 30000ms”Cause. One of two things, and the message does not say which (the code is timeout either
way).
- The client’s default
timeout(30 s) bounds the whole request, uploads included. A file of a few MB over a testnet or the public gateway takes longer. - The upload is direct (
deferred: false, the default) against a Bee node in dev mode, which serves only deferred uploads and never answers a direct one.
Fix. For the first, pass a longer timeout in the call’s requestOptions — the third argument
of uploadData, the fourth of uploadFile:
await client.uploadData(data, {}, { timeout: 600_000 })await client.uploadFile(file, undefined, {}, { timeout: 600_000 })or set timeout on the client for every call. For the second, ask the node with getNodeInfo()
and set deferred from beeMode === 'dev':
const { beeMode } = await client.getNodeInfo()await client.uploadData(data, { deferred: beeMode === 'dev' })No partition available — all slots are held by other devices. on a single device
Section titled “No partition available — all slots are held by other devices. on a single device”Cause. The first stamped write was refused by the node — it does not know the batch, because
the batch was bought moments ago or on a different node — and the write coordinator read the
refusal as contention from another device
(#765); the code is partition-contended. An
expired drive used to land here too, and so did one whose stored record already said
exists: false or usable: false; now the session refuses before the coordinator — The account's drive has expired with uploadUnavailableReason set to stamp-expired, or The account's drive is not usable with stamp-not-usable — as upload-unavailable with that reason.
Fix. A batch the node has not ingested yet needs a moment after purchase; the session says so
as stamp-warming-up and onConnectionChange fires when it is over. Otherwise check the drive:
getPostageBatch() reports exists and usable from a real node, and connectionInfo.canUpload
with uploadUnavailableReason says whether the session will stamp at all. See the
upload availability table.
Signed in, and every upload fails
Section titled “Signed in, and every upload fails”Cause. connectionInfo.identity being set does not mean the session can upload. A fresh
Swarm ID has no drive, so without a subsidisedGatewayUrl every first-time user’s upload fails.
Fix. Gate uploads on connectionInfo.canUpload, and show uploadUnavailableReason when it is
false: no-stamp and stamp-expired are the user’s to fix (attach, buy or renew a drive),
stamp-not-usable is the user’s too (open the drive in Swarm ID, which refreshes its record),
stamp-warming-up clears by itself within a minute, stamper-failed is a bug to report. Pass the public gateway as subsidisedGatewayUrl for a
free tier. See Quick Start and
Why Uploads Are Unavailable.
Iframe not initialized after sign-in
Section titled “Iframe not initialized after sign-in”Cause. The element the button container lives in was unmounted — typically rendered only
in the signed-out branch of the UI — which destroyed the proxy iframe with it. Every later call
has no iframe to talk to, and a later popup has no opener. Through the library it is a
SwarmIdError with code invalid-state.
Fix. Keep the container mounted for the life of the page, in every state. See Quick Start.
Failed to open authentication popup
Section titled “Failed to open authentication popup”Cause. The browser blocked the popup: connect() was not called from a user gesture, or a
blocker is on. The code is popup-blocked.
Fix. Call connect() synchronously from the click handler, or render the iframe’s own
button. The client opens the popup from the iframe or the page as the storage situation
requires, so an app’s own button works on partitioned storage too.
[SwarmIdClient] Rejected message from unauthorized origin, several times a second
Section titled “[SwarmIdClient] Rejected message from unauthorized origin, several times a second”Cause. Window messages from React DevTools, Vite or Next.js HMR, warned about before the client checks whether the message even came from its iframe.
Fix. Nothing on your side; the warning is noise (#759). A real origin problem shows as the iframe never becoming ready, not as this line.
308 and then 404 on /bzz/<reference>/
Section titled “308 and then 404 on /bzz/<reference>/”Cause. A raw-bytes reference — the output of uploadData — asked of the manifest endpoint.
Fix. Retrieve uploadData output at /bytes/<reference> or with downloadData. Read
uploadFile output with downloadFile: its default reference is 128 hex characters and carries
the decryption key, which must never go into a gateway URL. /bzz/<reference>/ is for a plain
one only (encrypt: false). See The Public Gateway.
No manifest at this reference; a reference from uploadData needs downloadData.
Section titled “No manifest at this reference; a reference from uploadData needs downloadData.”Cause. The same crossed pair, reached through the library: downloadFile given the output of
uploadData.
Fix. downloadData for uploadData output, downloadFile for uploadFile output. See
downloadData.
getNodeInfo() fails
Section titled “getNodeInfo() fails”Cause. The public gateway has no /node endpoint.
Fix. Do not gate anything on it. It exists to detect a dev-mode node; against the public
gateway keep the default deferred. See The Public Gateway.
@snaha/swarm-id runs in the browser only on the server
Section titled “@snaha/swarm-id runs in the browser only on the server”Cause. Importing the package is harmless, but new SwarmIdClient() needs window, so a
client constructed at module scope in a file that renders on the server (Next.js App Router,
SvelteKit with SSR) throws there. Before the guard this surfaced as a bare
ReferenceError: window is not defined from inside the package.
Fix. Construct the client in code that runs only in the browser: an effect, onMount, or a
branch on typeof window !== 'undefined'. See Quick Start. Code
that has no browser at all — a server, an agent — uses @ethersphere/bee-js with the drive’s batch
id and signer key instead; a headless client is #770.
A session approved on localhost is gone behind a tunnel or on a preview URL
Section titled “A session approved on localhost is gone behind a tunnel or on a preview URL”Cause. The app secret is derived from the app’s origin, and a tunnel hostname or a preview deployment is a different origin — so a different app, with a different secret and different derived keys.
Fix. Expected. Settle the production origin before anything derived from the app secret is used as an identity. See Key Derivation.
The proxy iframe rejects every message behind ngrok
Section titled “The proxy iframe rejects every message behind ngrok”Cause. The dev server’s own origin guard, not Swarm ID: Next.js refuses dev requests from an
origin other than localhost unless the host is listed.
Fix. Add the tunnel host to allowedDevOrigins (Next.js) or the equivalent. See
Local Development.
A proxy error with nothing to branch on
Section titled “A proxy error with nothing to branch on”Every failure used to cross the bridge as one string — status, Bee’s error body and the cause
flattened away (#761). Every rejection is now a
SwarmIdError: branch on error.code, and for bee-rejected read status, beeMessage and
url. See Errors. The message itself is unchanged, so what was logged before
still reads the same.