Things will go wrong. This page lists the failure modes that Dropbear is designed to handle, what they look like from the outside, and what you do about them. ## Network Blip **What happens:** the run aborts with a stage-specific exit code (10 transient, 11 integrity, 12 list). **On disk:** nothing destructive. The state DB still reflects the pre-sync world, the bucket has whatever was uploaded so far (orphan blobs — harmless; future GC will reclaim). **What you do:** rerun `dropbear sync`. The pipeline is idempotent — blobs that already exist in the bucket are skipped, the manifest is rebuilt from scratch, the head is republished. There is no "partial sync to clean up." ## Device Unplugged **What happens:** `dropbear sync` fails identity validation and exits with code 3 (offline). **On disk:** nothing. **In the bucket:** nothing. Crucially, no tombstones are emitted for the files Dropbear can't currently see. A USB drive being unplugged is _not_ a delete. **What you do:** plug the drive in. Rerun. ## Auth Revoked **What happens:** exit code 9 (unauthorized) at whichever pipeline stage first hits the bucket. **On disk:** nothing. **What you do:** rotate / refresh credentials in your `DROPBEAR_S3_*` environment, rerun. ## Hash Mismatch **What happens:** during the download phase, Dropbear fetches another device's head, then fetches the manifest it points to, and verifies that the manifest's bytes hash to `manifest_sha256` from the head. If they don't match, the run aborts with exit code 11. **Why it matters:** either the bucket has been tampered with, or you've hit a bug. Either way, Dropbear refuses to proceed because a forged manifest could direct your device to download an attacker-chosen blob under an existing path. **What you do:** investigate. The bucket should not produce mismatched objects under normal operation. If you have a bug report, this is one. ## Simultaneous Edits **What happens:** the device that pulls _second_ sees that its local file diverges from the manifest entry it pulled. Instead of overwriting, it writes a conflict copy: `.conflict--.`. The local row flips to `StatusConflict`, which excludes it from this device's manifest until you resolve. **On disk:** both versions present. Original at the original path; the other device's version in the conflict-suffixed file. **What you do:** look at both, pick a winner, delete the conflict file, edit the local file if needed. The next `sync` republishes the resolved state. (A future `dropbear resolve` command will make this less of an implicit dance.) ## Multi-Device Disagreement **What happens:** three or more devices have diverged on the same path and Dropbear can't decide which device's content to materialize as the conflict file. The run skips that path with a warning and leaves local untouched. The path stays in conflict-skip status until enough devices re-converge that the divergence has a clear winner, or the user manually resolves. **What you do:** consolidate edits on one device, or use `download-only` / `upload-only` modes to break the symmetry. ## Remote Head Fetch Fails **What happens:** transient errors or auth blips on a specific device's head are reported as a skip counter (warning to stderr; the rest of the run continues). That device's content does not influence this run, but the next run will retry. **What you do:** nothing immediate. If a specific device is _consistently_ skipped, that's worth investigating. ## Disk Full **What happens:** the download writes to a temp dir under the root and atomically renames into place on success. A disk-full failure leaves the temp dir, aborts the run with a stage error. **On disk:** orphan temp directories under `.dropbear/restore-tmp/`. Cleaned up automatically on the next run. **What you do:** free space, rerun. ## State DB Corrupted **What happens:** the SQLite file under `.dropbear/state.sqlite` is unreadable. **What you do:** you can rebuild local state from the bucket using `dropbear restore --from ` — it repopulates the state DB from the manifest you last published. You lose any unpublished work since that manifest. If you have unpublished changes, copy them aside first. ## Escape Hatch If you've lost confidence in a root's local state — botched edit, weird metadata, suspected bug — you can always: 1. Copy your live working files aside. 1. Delete `.dropbear/state.sqlite`. 1. Run `dropbear restore --from ` to repopulate from the bucket. 1. Compare your set-aside copy with the restored state and merge by hand. This isn't pretty, but it's always available as an escape hatch because the bucket is the source of truth.