UniClipboard

Troubleshooting

Triage path for sync, pairing, clipboard permissions, log collection, and emergency reset.

Edit on GitHub

UniClipboard issues fall into a small set of layers: is the daemon running → is pairing established → can the peer be discovered → does transport work → did the representation land. Walk them in that order. Each section below tells you which signals to look at and which commands to run.

If the problem began after upgrading from 0.19, start with Upgrade from 0.19 to 1.0. It explains the expected data backup, search rebuild, cleared device list, and re-pairing flow.

Before guessing, run uniclip space status and uniclip member list on both ends. The "should be online" feeling rarely matches what's actually on the wire.

Start here: 30-second triage

SymptomMost likely layerJump to
Command says "daemon not running"DaemonDaemon
join <code> errors out or hangsPairingPairing failures
Both online but members doesn't list each otherDiscoveryPeer not appearing
Peer is visible but sync is slow / files stallTransportStuck on relay / slow sync
You copy something and the peer gets nothingClipboard permissionClipboard permissions
Search returns nothing or "index not ready"Full-text indexSearch & index
Phone can't reach the desktop / 401 / corrupt imageMobile syncMobile sync (iOS Shortcut)

Daemon

Every CLI sync command depends on the daemon. Use uniclip run for a foreground daemon, or uniclip service start for a user service. Use uniclip service status to inspect service and HTTP health, and uniclip service stop to stop the user service.

uniclip space status            # summary
uniclip space status --json     # stable fields, easy to diff

Key fields:

  • daemon.running — whether the process is alive.
  • space.bound — whether the current profile is bound to a space. false means you haven't run uniclip space init or uniclip space join yet.
  • network.endpoint — this device's iroh node ID. Switching Wi-Fi doesn't change it; if it changes, you switched profile or keyslot.
  • network.relay — relay domain in use; null means direct.
  • peers[].reachability — per-peer reachability snapshot.
  • membership_convergence — whether the active space is fully connected: complete, converging, waiting_for_upgrade, or blocked.

If daemon.running = false but uniclip service start fails, run it in the foreground to capture the trace:

uniclip run -v

Read the error printed by the foreground process. If it cannot find or start uniclipd, reinstall the CLI or put the matching uniclip and uniclipd files back in the same directory. The desktop app and CLI can normally share one profile and one daemon.

Daemon log shows "system secure store is unavailable for this run"

This WARN means the daemon could not use the freedesktop Secret Service (GNOME Keyring / KWallet) at startup. What happens next depends on where this profile's Key Encryption Key (KEK) already lives:

  • Profiles that already use the file key store — versions before 1.0 degraded to a file under the app's data directory (keyring/) whenever the Secret Service probe failed. Those profiles keep using that file, whether or not a secret service becomes available later. The log shows using the legacy file key store. Nothing is copied, moved, or deleted between the two stores.
  • Profiles without a file key store — the daemon does not create an empty file store as a substitute. Startup stops with "The app could not start", and the logs show engine startup failed with an error code. Make the Secret Service reachable, then restart the app.
  • Profiles with entries in both places — when the Secret Service holds only some of the entries in the file store, the daemon cannot tell which copy is complete. It stops without changing either store, and the log shows hold different entries. Keep both, export diagnostics, and contact support.
  • Once a profile with a file key store has unlocked while the Secret Service could be consulted, the daemon records which store it used in secure-storage-source.json in the app's data directory, and uses only that store from then on. A run during a Secret Service outage never writes this record. If the recorded store is unavailable, startup stops instead of switching to the other store. Do not edit or delete that file.

Two situations commonly make the Secret Service unreachable:

Snap sandbox — AppArmor refused the D-Bus call because the password-manager-service plug is not connected:

sudo snap connect uniclipboard:password-manager-service
# then restart the app

Minimal Wayland session (hyprland / sway, etc.) — the session looks like a desktop (DISPLAY and DBUS_SESSION_BUS_ADDRESS are set), so the daemon tries the system keyring, but no secret service is running (the log reads The name is not activatable), or one is running but locked with no prompter to unlock it. The probe is bounded by a short timeout, so the daemon reports the problem after a few seconds instead of hanging. Run an unlocked secret service in the session, for example:

gnome-keyring-daemon --start --components=secrets
# better: unlock it automatically at login via pam_gnome_keyring,
# or enable KeePassXC's "Secret Service Integration"

Do not delete the app's keyring/ directory to "reset" storage: for profiles that use the file key store it holds the only copy of the KEK, and removing it forces passphrase recovery.

Pairing failures

Invite says "invalid or expired"

Invitation codes are short-lived and single-use. Once consumed or expired, regenerate one on the sponsor:

uniclip space invite        # issue a fresh one on the sponsor

Don't treat invites like long-lived credentials or paste them into a chat history — they're designed to live only until the next handshake.

Correct invite, but the handshake hangs

The handshake runs PAKE to verify the passphrase. If the peer never appears in members:

  1. Confirm clocks on both ends agree to within a few minutes. Argon2id and signature checks are sensitive to clock drift.

  2. On the sponsor, uniclip space status --json | grep handshake shows whether it's waiting for a joiner. If nothing arrived, discovery itself is broken — jump to Peer not appearing.

  3. The default handshake TTL is roughly three minutes. After that the sponsor drops the invite and the joiner sees "invitation expired". Just space invite again.

  4. Sponsor running Tailscale or a similar overlay? By default, Tailscale CGNAT (100.64.0.0/10) and IPv6 ULA (fd7a:115c:a1e0::/48) addresses are stripped from the invitation, so the joiner only sees unreachable LAN addresses and dial attempts hang. On the sponsor, enable Settings → Network → Allow overlay network addrs and restart the daemon so Tailscale addresses get included. Clash TUN fake-ip (198.18.0.0/15) and IPv4 link-local (169.254.0.0/16) are always filtered with no opt-out — those interfaces aren't real dial targets, so leave UniClipboard on a physical NIC instead.

    This toggle only affects desktop ↔ desktop pairing. Mobile sync has its own Bind IP dropdown (Configure modal / device-card dialog), which always lists Tailscale CGNAT interfaces regardless of Allow overlay network addrs — mobile pairing is a manual pick, so a Tailscale-reachable phone can be paired even with the toggle off.

"passphrase mismatch" or kicked right after joining

Wrong passphrase makes the key rewrap fail. This is by design — the sponsor never sees the bad passphrase in plaintext. Double-check and retry.

A lost passphrase cannot be read or recovered. If this device is already unlocked and is the space's only device, use Reset passphrase in this invitation dialog, or go to Settings → Security & Privacy, to choose a new one without losing local history. If the space has multiple devices, remove the others first. If no device can unlock the space, you must reset and start over.

Peer not appearing

Discovery runs three lookups in parallel: mDNS, rendezvous, cached direct addresses. Any hit wins. If the peer never shows up in members:

Same Wi-Fi? Rule out AP isolation

Many home routers and café Wi-Fis enable client / AP isolation by default, which drops mDNS and unicast traffic between devices on the same SSID.

  • Look for "AP Isolation", "Client Isolation", or "Wireless Isolation" in the router admin and turn it off.
  • Guest networks usually leave isolation on permanently — move both devices to the main network.

Different networks? Confirm rendezvous reachability

Cross-network discovery depends on rendezvous over HTTPS. On strict corporate networks an inspecting middlebox may break HTTPS egress entirely.

  • Switch one device to a phone hotspot and retry. If it works there, the original network's egress policy is the culprit.
  • Firewall allowlists need to permit iroh's default rendezvous and relay domains. Inspect uniclip space status --json (network field) for the exact hosts in use.

Clock drift?

Signed address records carry timestamps. If one end's clock drifts more than a few minutes, the other side rejects its records as expired — producing the "looks online, can't find each other" pattern.

Stuck on relay / slow sync

A non-empty network.relay in uniclip space status means the path is relayed — it works, but with worse latency and bandwidth than direct. If both devices are on the same network and you still see relay use:

  • Symmetric NAT. Some carriers and mobile networks allocate ports unpredictably, breaking hole-punching. Switching networks (or enabling IPv6) usually fixes it.
  • IPv6 disabled along the path. Direct fails over to IPv4 NAT punching, which is more fragile.
  • Corporate networks. Locked-down outbound UDP forces relay use, and some of these networks block the relay too — in which case UniClipboard simply isn't usable on that network.
  • A local proxy is intercepting relay traffic. Overseas relay + a local proxy (Clash / Surge / etc.) on the same machine usually means the proxy is also forwarding relay traffic, bottlenecking bandwidth at the proxy egress and degrading UDP/QUIC. Route the relay domain to DIRECT — see Self-host an iroh relay — Direct-connect the relay if you also run a local proxy.

The relay only ever sees ciphertext. Its availability affects performance and reachability, not confidentiality. See Pairing & sync — Transport.

File-class payloads use a chunked blob protocol (see What syncs — Large payloads), which resumes after disconnects and wake-from-sleep. If a single big file has been creeping along for hours at near-zero rate, a chunk is probably stuck without retrying. On the sender, uniclip service restart can help when the sending daemon is a user service; otherwise stop its existing owner and run uniclip run.

Clipboard permissions

If a copy produces nothing on the peer, and uniclip watch shows no event either, the local side likely never read the clipboard.

The recorded global Quick Panel hotkey requires Input Monitoring. Grant it in System Settings → Privacy & Security → Input Monitoring, then fully quit and relaunch the app.

The optional modifier double-tap trigger uses a separate Accessibility grant. UniClipboard checks this permission silently and keeps the selector disabled until it is available. Click Open Accessibility settings beside the selector; if UniClipboard is not listed, click + and add /Applications/UniClipboard.app. Return to the app after granting access. Clipboard capture itself does not require Accessibility.

Windows usually needs no extra grants. If uniclip watch is silent:

  • Antivirus or EDR may be blocking the clipboard hook in UniClipboard.exe / uniclip.exe. Check the event log or the AV quarantine.
  • Inside an RDP session, the clipboard is separate from the host. Turn off RDP clipboard redirection and retry.

The desktop session matters more than the distro:

  • Wayland: ext-data-control-v1 (GNOME / mutter ≥ 47, Plasma 6) and wlr-data-control (Sway / Hyprland and other wlroots compositors) are supported natively — no bridge tooling required. When neither protocol is available, capture falls back to XWayland (the X11 path) automatically.
  • X11: works out of the box with the built-in native clipboard listener; no external clipboard tools (xclip / xsel) are needed.
  • Headless servers: with no X / Wayland, only the CLI's send / watch features work; GUI clipboard capture isn't available.

Search & index

uniclip search status reports the full-text index state.

uniclip search status      # ready / building / missing
uniclip search rebuild     # synchronous rebuild (blocks until done)

Common cases:

  • "index not ready" — daemon just started or post-upgrade rebuild in progress. uniclip search status reports progress.
  • Old entries missing after rebuild — they may have been GC'd by the retention policy during upgrade. The hidden command uniclip dev dump-clipboard --limit N lets you confirm whether they're still in history at all.
  • Corrupt index file (rare) — usually after a SIGKILL during writes. Delete the index subdirectory under the data folder, then uniclip search rebuild. The clipboard history itself lives in a separate file and isn't affected.

Mobile sync (iOS Shortcut)

The mobile companion runs over plain HTTP with Basic Auth (TLS comes from a reverse proxy) — completely separate from the iroh peer mesh. Most failures fall into one of these buckets.

Phone can't open the URL

Symptom: tapping the install URL or running the Shortcut times out without ever showing a 401 / 4xx response.

  1. Can the phone reach the address you advertised? In the default setup the phone and desktop must be on the same Wi-Fi / subnet; if you're using a server node (public HTTPS) or Tailscale / VPN, make sure the phone is going through that channel. Mobile sync itself has no relay and no NAT punching.
  2. The advertised IP must be reachable from the phone. The desktop socket always binds to 0.0.0.0, but the URL baked into the install link must be a real LAN IPv4 the phone can dial. The Configure dialog enforces this: with Bind IP on Auto, the "Current listening address" row expands inline into every RFC1918 candidate — copy the one the phone is on; with a specific interface picked, the row shows that single fixed URL. From the CLI, pass --ip <LAN_IPV4> to uniclip mobile network set.
  3. Check listener state. uniclip mobile status reports lan_listener_error if the daemon tried to bind and failed (port in use, permission denied). Resolve the underlying error or pick a different port.
  4. Firewall on the desktop OS. Confirm inbound traffic on port 42720 (or your custom port) is allowed for the LAN profile.
  5. Did you change the IP / port recently? A daemon restart is required to apply listener changes; the Shortcut on the phone also needs its url field updated to match.

401 Unauthorized

The username or password is wrong. Reasons:

  • The plaintext password is shown once at registration. If you lost it, click Rotate password on the device row (or uniclip mobile revoke <id> + add) — there is no way to recover the original.
  • The Shortcut on the phone may still hold an old credential after rotation. Re-edit the url / username / password fields.

Image from iPhone arrives broken / not visible

The desktop sniffs the magic bytes of incoming uploads to recover the correct image/* MIME (iOS Shortcuts often sends application/octet-stream regardless of file extension). The sniffer landed in 0.7.0-alpha.6; if JPEG / PNG uploads render as blank or invalid pasteboard images, confirm with uniclip --version and upgrade to 0.7.0-alpha.6 or newer.

Public Wi-Fi

Don't run the LAN listener on coffee shop / airport / conference Wi-Fi. The v1 wire format is plain HTTP with Basic Auth — anyone on the same SSID can sniff your clipboard. If you need to use it on an untrusted network, set the listener to disabled first (uniclip mobile network off) and re-enable on a trusted network.

Changed the LAN IP / port?

Two things have to happen for the new value to be live:

  1. Restart the daemon so the listener rebinds.
  2. Update the Shortcut's url field on the phone to match the new advertised URL.

uniclip mobile status is a fast way to confirm what the daemon is currently advertising.

Collecting logs

The fastest way to gather everything for an issue report is the built-in export, which zips the GUI, daemon, and CLI logs from the last 24 hours into your Downloads folder:

  • GUI: Settings → General → Export logs.
  • CLI: uniclip debug export-logs (use --since-hours <N> to widen or narrow the window).

If a problem is hard to reproduce, enable verbose logging first (Settings → General → Debug mode, or uniclip debug on), reproduce, then export. Turn it back off and restart afterwards.

If the app is stuck on its startup failure screen and Settings is unavailable, click Export logs on that screen and choose a save location. This entry point works without a running background service and packages the retained GUI, daemon, and CLI logs in the current app log directory, rather than limiting the export to the last 24 hours. Retry restarts the background service and shows progress on the screen. Contact author opens the GitHub support page without uploading any logs automatically. Expand Error details to inspect the reported failure.

If you'd rather grab the files by hand, logs live in each platform's conventional log location (separate from the encrypted history). Only the last 7 days are kept per process; older files are removed automatically:

PlatformPath
macOS~/Library/Logs/app.uniclipboard.desktop/
Linux~/.local/state/app.uniclipboard.desktop/logs/
Windows%LOCALAPPDATA%\app.uniclipboard.desktop\logs\

On Linux, if the state directory is unavailable, logs fall back to the data-local root instead: ~/.local/share/app.uniclipboard.desktop/logs/.

Each process writes its own file: uniclipboard-gui, uniclipboard-daemon, or uniclipboard-cli. With UC_PROFILE set, the directory carries a suffix (app.uniclipboard.desktop-dev). See Install — Where data lives.

Reproduce while capturing — much better than digging through old logs:

# Run the daemon in foreground with debug-level output piped to the terminal
uniclip stop
uniclip run -v

When filing an issue, please attach:

  • uniclip --version, OS and version.
  • uniclip space status --json from each end.
  • Repro steps with timestamps; the log slice covering that window is enough — no need to upload the full file.
  • Don't paste database files, invitation codes, or space passphrases into the issue.

Emergency reset (last resort)

If the saved system key is missing but you remember the original encryption passphrase, try Recover local data first. The recovery screen deliberately has no one-click erase action. Resetting is not a required recovery step.

The GUI reset option below is only available on the ordinary content unlock screen, not on the recovery, startup or upgrade screens. Disabling automatic content unlock does not stop normal background sync. Contact the author and back up your data before considering a reset.

The operations below destroy local clipboard history and can't be rolled back. Use them only after the steps above failed.

If the app gets you all the way to the unlock screen (passphrase prompt) but you can't recall the passphrase, you don't need the CLI:

  1. On the unlock screen, click Forgot passphrase? Reset and start over. The link sits at the bottom of the page and is also exposed inside the passphrase modal.
  2. Type RESET in the confirmation dialog and press Reset.
  3. The app deletes the on-disk keyslot and KEK on this device, clears SetupStatus, and drops you back at the setup screen. From there run uniclip space init for a fresh space or uniclip space join from another device.

This is the same destructive operation as the CLI tabs below — local history on this device is unrecoverable afterwards. Other devices in the space are unaffected (see the warning below).

uniclip stop
# Then delete the profile's data directory (path above).
# Linux example:
rm -rf ~/.local/share/app.uniclipboard.desktop

After cleanup, uniclip space init or uniclip space join starts fresh. The keyring's KEK entry will be overwritten by the next space init.

  1. Quit the GUI; uniclip stop.
  2. Uninstall the package:
    • macOS Homebrew: brew uninstall --cask uniclipboard && brew uninstall uniclipboard
    • Windows: Settings → Apps → UniClipboard → Uninstall (or Control Panel → Programs & Features)
    • Linux Snap: sudo snap remove uniclipboard
    • Linux COPR (dnf): sudo dnf remove uniclipboard && sudo dnf copr disable mkdir700/uniclipboard-alpha
    • Linux .deb: sudo apt remove uniclipboard
    • Linux .rpm (one-shot install): sudo dnf remove uniclipboard
    • AppImage: delete the .AppImage file.
  3. Delete the data directory (paths above).
  4. Manually clean keyring entries:
    • macOS Keychain: search uniclipboard, delete entries.
    • Windows Credential Manager: Control Panel → User Accounts → Credential Manager → Windows Credentials, remove uniclipboard:*.
    • Linux Secret Service: use seahorse or secret-tool to wipe the uniclipboard namespace.

Manual .deb/.rpm packages now use uniclipboard. Older releases used uni-clipboard; install the new downloaded package with sudo apt install ./package.deb or sudo dnf install ./package.rpm to replace it in one transaction. The application data, keys, and executable paths stay the same. If you have not migrated, uninstall the older package with sudo apt remove uni-clipboard or sudo dnf remove uni-clipboard. COPR packages follow their separately maintained release.

Resetting one device does not revoke it on the other devices in the space. To make a device disappear from the space, revoke it from another online device — clearing local data alone does not invalidate its node ID's trusted status.

Still stuck?

  • Skim the FAQ — many "issues" turn out to be intentional behavior, not bugs.
  • If something is genuinely off, file an issue at github.com/UniClipboard/UniClipboard/issues. Follow the log collection checklist above.
  • For security issues, use the private disclosure channel listed in SECURITY.md — don't open a public issue.

On this page