Browse docs
Docs / Reference / Diagnostics & Error Reference

Diagnostics & Error Reference

When something goes wrong, Swarmfile names the problem in one of a few places. This page maps the surfaces - doctor checks, status counters, health endpoints, and error codes - to plain meanings and next steps.

Start here#

SurfaceWhat it isHow to reach it
Desktop App → Settings → DiagnosticsLive checks, report file, Repair drive, Reinstall…, update checkThe tray's settings
Status pill (header)Mount location, sync state, the hub's reason for any pauseClick it
swarmfile statusThe same snapshot as JSON or prose: counters, peers, bandwidthCLI
swarmfile-doctorStandalone probe suite that runs with no engine and no sign-inCLI
swarmfile doctorRuns the same probes through a live engineCLI
Hub error codesMachine-readable reasons on API refusals (bring-your-own scripts)JSON bodies

swarmfile-doctor writes a JSON report on every run and returns a verdict:

swarmfile-doctor --json --report doctor-report.json   # full detail
swarmfile-doctor --repair --yes                        # reinstall the package (keeps your queue)

Exit codes: 0 everything passed, 1 at least one failure, 2 warnings only. The report defaults to ~/.cache/swarmfile/last-doctor.json (macOS/Linux) or %USERPROFILE%\Swarmfile\last-doctor.json (Windows).

Engine logs live in the cache directory (~/.cache/swarmfile on macOS and Linux, %LOCALAPPDATA%\swarmfile on Windows) as engine.log; the Desktop App writes tray.log beside it, and macOS mount-helper output lands in ~/Library/Logs/fuse-t/fuse-t.log. Diagnostics has an Open log directory action. Increase detail with RUST_LOG=swarmfile_engine=debug.

Status counters#

swarmfile status (and the Desktop App's panels) report these; the names are the JSON fields from swarmfile status --json:

CounterMeaningWhat to do
pendingUploadsBlocks queued on this machine awaiting cloud upload, plus closed files whose save is still runningWait; check for connection trouble
peerPendingUploadsIn-flight uploads reported by other machines on this branchUsually informational
pendingCreatesFiles/folders created locally and queued for the hub (an object with the count, stuck rows at six or more failed attempts, and the oldest age)They land automatically; see Coding Agents
commitsPendingBytes uploaded but the commit hasn't landed (retrying, rate-limited, quota-held, or locked)Check quotaHeldCommits and connectivity
quotaHeldCommitsCommits refused on billing grounds, retried on a 15-minute cadence; spendCapHeldCommits is the subset held by the org's spend cap, which the tray names ("Waiting on spend cap")Raise the limit or free space; retries resume
commitsRefusedCommits the hub keeps refusing for other reasons (a subset of commitsPending)Investigate the refusal; usually policy or conflict
abandonedGroupsUpload groups that exhausted retries or hit a plan capswarmfile sync stuck lists them; re-save after fixing the cause
failedWritesGuest-session writes permanently given up (guest replay only)Re-open the guest session and retry
activeLocksWrite locks this engine currently holdsInformational
checkoutLocksLong-lived per-file checkout locks (explicit, git-LFS) you holdRelease with unlock / offline return when done
scopeReservationsOffline scope reservations this engine holds - one row can cover a whole subtree; Pack & Go uses these rather than per-file locksswarmfile offline status
checkoutRenewFailuresRenewal passes that re-issued nothing - reservations at risk of lapsingReconnect and re-prepare before the lease ends
checkoutExpiringSoonReservations expiring within 24 hoursExtend or return; see Working Offline
peersLAN/office/seed peers currently reachable, with RTTMore peers = faster reads for shared files
bandwidth.bytesIn / bandwidth.bytesOutTransfer volume for this sessionUseful when a link is saturated
blockStorePinned blocks and local cache usageswarmfile cache status / hydrate status
authSession state ("signed out" when there's no usable session)Sign in again
recentErrorsA ring of the most recent engine errorsOften the fastest pointer to the root cause
lastSequenceIdLatest committed sequence known hereDiagnostic for history lag
mounted / mountState / mountErrorWhether the mount is live and, if not, why (a stable code plus a user-facing sentence)See the mount errors below

Health endpoints#

There is no default health port - the server starts only when SWARMFILE_HEALTH_PORT is set (typical choices: 8080 in container deployments, 9100 for a seed node). It binds 0.0.0.0:<port> and serves exactly:

  • GET /livez - a cheap {"status":"ok"} for liveness probes (Kubernetes and friends). Allowed from anywhere.
  • GET /healthz - the detailed snapshot (version, uptime, peer counts and RTT, pin/cache stats, encryption state). Loopback-only: a non-loopback caller gets 403 {"error":"loopback only"}, because the detail exposes fleet topology.
  • Anything else - 404.

Doctor checks#

swarmfile-doctor reports one row per check. The whole report is capped at 10 seconds; if the cap fires, a synthetic report check fails, and a probe that couldn't complete counts as a failure rather than a silent pass. Each of the three network checks - hub https /health, oidc token, r2 path - retries one fast transient failure (a connection error or a 5xx) before it reports Fail, so a brief hub rollout blip doesn't read as an outage; a definitive refusal like an expired token's 401 is reported on the first reply. The ones that name a common failure:

CheckFailing usually means
engine-runningNo engine for this user; sign in / start the app, or expect the standalone checks below
install-layout / updater-helper-taskA partial or relocated install (on macOS, a pre-R41 layout the updater can no longer reach); reinstall (helper task is Windows)
dns <host>DNS resolution for the hub/identity/storage host failed
hub https /healthThe hub host is unreachable or blocked; proxy/firewall issue
hub deep healthThe hub is up but a dependency (storage, workers) is degraded
oidc tokenThe sign-in session expired, was revoked, or the account isn't a member of the configured org; sign in again
hub deep healthThe hub is up but one of its dependencies (D1, R2, the IdP issuer, its own clock) is degraded
r2 pathCloud storage credentials, presigning, or the block path failed for this org
iroh quic dial / mdns listenPeer-to-peer path blocked (firewall, VLAN, VPN); falls back to the hub
host firewall / macos local networkOS firewall or macOS Local Network consent blocks LAN discovery
uploads in flight / in-flight streamingUploads or reads waiting on in-flight bytes exist - expected during activity, informative otherwise
fuse-t mount helper / mountThe macOS mount helper died, or the mount point is wedged or absent; Repair drive
duplicate mount stackTwo engines are competing for the same mount point
exclusive writesNever fails - informational: names the drives in the opt-in exclusive-write mode
history retentionNever fails - informational: the active project's retention mode (every saved version kept and cold-archived, or named commits only). "Not checked" without a project scope or on an older hub
upload quotaBlocks are parked because the org is at a billing limit - see the count/bytes/age in the row
planSubscription inactive, a feature isn't in the plan (e.g. seed mode), or a metered dimension is ≥80%
pack and go policyA SWARMFILE_PACK_AND_GO_POLICY value that isn't allowed/disabled - failing closed
previous runThe last engine run ended abnormally (panic or unexpected exit) - the row points at engine.log
url schemeswarmfile:// links (Open in app, sign-in, Explorer's Swarmfile menu) won't reach this install: no app is registered for the scheme, another app or install owns it, or (macOS) several copies of Swarmfile compete for it and a link may start an old one. Fix link handling re-registers this install; on Windows, a registration pointing at another install needs Repair from Settings › Apps
install-layoutWarning only: the engine isn't where the installer puts it - moved out of the app bundle, or a pre-R41 macOS install whose LaunchAgent still runs a stale /usr/local/bin copy. On macOS it also warns when /usr/local/bin is missing the CLI-tool links (a .dmg-only install the tray couldn't repair), since swarmfile is then not on PATH.

Engine and mount errors (what the app shows)#

Code / messageMeaningFix
not_signed_inThe engine has no usable sessionSign in from the app
not_a_memberThe session doesn't include the configured org/projectSwitch organization or ask for an invite
project_deletedThe mounted project was permanently deletedMount another project; contact support about recovery within retention
config_parse_errorA config.json couldn't be read, so the engine came up without a projectThe message names the file and the parse position - fix it and restart; see Engine Config File
mount_failed / no_free_drive_letterWindows could not attach the mountFree a drive letter or choose one in the app; swarmfile mounts open auto
drive_letter_in_useThe chosen letter (or Auto's candidates) are all takenThe message names what holds it; pick another
mount_point_not_emptyWindows refuses to mount over a non-empty folderChoose an empty folder
pack_and_go_disabledAn administrator disabled bulk offline reservationUse a per-file lock or ask your admin
confirmation_requiredA destructive CLI command was run without --yes in a non-interactive contextRe-run with -y after checking what it will delete
usage_errorA CLI invocation didn't parse (unknown command, flag, or argument); emitted as JSON when --json is present, with clap's kindFix the invocation - see Scripting against the CLI
changelists_openA branch/project switch was refused because staged work is openSubmit, cancel, or --park first
is_default_mountYou tried to close the boot mount on its ownClose another mount, or quit the engine instead
shared_branch_contextThe mount shares the engine's branch contextRe-open it with mounts open --branch <name> to make it independently switchable
already_running / project_switch_runningAnother switch or long job of that kind is in flightWait for it to finish, then retry
pending_createA lock/comment/share on a file that is still being createdRetry after it syncs (swarmfile status → pendingCreates)

Hub error codes (for scripts and integrations)#

API refusals carry a machine-readable code. The ones most worth handling, in the order you'll meet them:

CodeMeaningTypical handling
bad_request, invalid_request, invalid_state, invalid_name, bad_cid, invalid_cid, bad_hashMalformed or out-of-order requestFix the request; don't retry blindly
credential_invalid, email_verification_required, email_not_verified, session_expired, session_revoked, unauthenticated, terms_acceptance_requiredAuth/session problemSign in again; verify email for share actions; accept updated terms
api_key_* (api_key_grant, api_key_org_mismatch, api_key_project_mismatch, api_key_scope_forbidden)API-key scope doesn't cover this operationUse a key scoped to the project/org, or mint a new one
forbidden, not_member, admin_role_required, idp_binding_rejectedNot permitted for this account/roleEscalate to an admin
org_mfa_required, org_email_verification_requiredThe org's authentication policy refuses this credentialEnroll an authenticator app / verify your email under Account settings, then sign in again - the refusal body's enrollUrl points there. Don't retry unchanged; a personal access token must be re-minted from a compliant session
owner_mfa_required, mfa_status_unavailableTurning on "require MFA" needs the acting owner's own confirmed factor (or the factor-status probe was unreachable)Enroll an authenticator app first, then retry the policy change
identity_conflictAn external-IdP sign-in conflicts with an existing Swarmfile account: its subject names a first-party user, or a principal provisioned by a different issuerContact the organization's administrator; sign in through the org's own SSO rather than a built-in Swarmfile account
entry_not_found, entry_deleted, project_not_found, project_deleted, path_not_found, not_a_file, source_gone, target_goneThe target is goneRe-list; treat as terminal
exists, name_conflict, id_conflict, name_takenCollision or illegal nameRename / resolve the conflict
entry_uploadingThe entry has no committed version yetWait for upload, then retry
chunk_missing, cid_mismatch, checksum_mismatch, size_mismatch, manifest_unreadable, manifest_too_large, tree_object_corrupt, tree_object_missing, commit_object_corrupt, commit_object_missingContent integrity/structure problemRe-upload the file; report if persistent
conflict_detected, conflict_unresolved, merge_conflict, stale_mergeConcurrent edits, or the target moved since the merge/conflict was preparedResolve the conflict (swarmfile conflicts resolve), then retry
(no code; the envelope's error text says target_changed / merge_candidate_changed)The file changed again after the conflict was recorded, or the automatic merge result changed after you previewed itRe-read the file and resolve against the newer version; run the merge attempt again before accepting. Match the text, not a code - the hub sends these two without one
lockedSomeone else holds the file, or a machine's Pack & Go scope reservation covers itWait, or request an unlock (swarmfile unlock-request); a scope reservation is released by its owner with swarmfile offline return
commit_mode_locked, policy_enforcedAn admin lock requires a different commit mode, or refuses the settingCheck the enforced mode with swarmfile config get-commit-mode, then use it
commit_race, head_changed, merge_in_progress, fork_in_progressHistory moved under you, or a merge/fork is runningRe-read, wait, then retry
branch_not_found, branch_mismatch, branch_locked, branch_has_open_mr, branch_has_active_children, merge_mainBranch rules prevented the actionUse the allowed path (merge the MR, delete children first, never merge into main directly)
not_approved, self_review, is_draft, not_draft, protected_branchMerge-request gatesGet approvals, un-draft, don't self-review
project_archived, storage_exceeded, quota_exceeded, spend_cap_reached, plan_restricted, keys_cap, subscription_inactive, too_many_entries, too_many_descendants, registry_too_large, batch_too_large, body_too_large, merge_too_large, too_many_cidsPlan or size limitFree space, upgrade, or split the request/project; merge_too_large means the merge exceeded the single-project merge capacity - land the branch in smaller pieces - otherwise retry after the allowance changes. spend_cap_reached is the dollar ceiling: the envelope carries capCents/usedCents/remainingCents (and keyLimitCents/keyId when a per-key budget was the binding wall) - raise the cap or free space and held writes resume on their own
project_storage_fullThis project hit its metadata ceiling (files and versions combined)Delete or purge files, delete stale branches, shorten history retention, or switch the project to Named commits only (the same guidance the owner notification carries) - see Project storage limit
checkout_requiredThe org hasn't completed subscription checkoutFinish checkout in Billing before creating projects
rate_limitedRequest budget exceededBack off and retry; see Rate limits
grace_period_inaccessibleThe org is in the post-unpaid 28-day windowResubscribe - see Data Portability
quarantinedRansomware detection quarantined the account; writes stop until an owner releases it (on Windows the drive stays mounted meanwhile, with saves held locally)Review and release from the quarantine panel - see Ransomware quarantine
project_key_unavailable, project_key_rotation_unsupportedEncryption key unavailable, or the project can't rotate (plaintext storage, or it has reached the maximum key generations)Check the project's encryption tier; contact support if the cap is reached
e2e_upload_unsupported, e2e_unsupported, e2e_not_supported, encryption_tier_not_publicThe operation isn't allowed for this tierUse the supported tier (e.g. LFS is rejected on E2E)
jurisdiction_incompatibleThe destination isn't in the org's pinned jurisdictionUse storage/a destination in the pinned region
share_too_large, block_not_in_share, block_session_expired, raw_byte_budget_exceededShare-link limits or a public-streaming budgetReduce scope, create a new share, or wait out the budget
too_many_webhooks, blocked_target, invalid_urlWebhook limits or an unsafe target URLDelete unused webhooks; use a public HTTPS endpoint
preview_budget_exhausted, preview_too_large, preview_type_unsupportedPreview generation budget, size, or type limitWait for the daily reset; serve the file directly or download it
too_many_active_jobs, too_many_concurrent_readsTemporary concurrency limitBack off and retry
invite_unavailable, org_not_empty, installation_exists, already_provisioning, storage_provisioningAdmin lifecycle stateComplete or wait for the pending operation
announce_unverifiedA seed node's announce failed node authenticationRe-enroll the node; see Self-Hosted Seed Nodes
org_migration_frozen, project_unreachable, async_unavailableA migration/maintenance stateRetry after it completes
not_found, forbiddenGeneric - the meaning depends on the operationUse your caller's contextual fallback; don't guess

The full set is generated from the hub's own routes and shipped in contracts/hub-schemas.json and the OpenAPI contract; an unrecognized code is preserved verbatim rather than dropped, so a script can always log it.

Exit codes#

BinaryCodes
swarmfile0 success; 1 failure (unreachable engine, transport error, no product equivalent); 2 actionable refusal or a usage error - under --json the two are distinguishable by code (usage_error vs the refusal's code) - see Scripting against the CLI
swarmfile-doctor0 all passed; 1 ≥1 failure; 2 warnings only. A usage error under --json prints the shared {"code":"usage_error",…} body, as every standalone tool now does
swarmfile-runnerThe engine's code (the alias re-execs it); 127 if the sibling engine is missing

Where to go next#