Troubleshooting
Triage path for sync, pairing, clipboard permissions, log collection, and emergency reset.
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
| Symptom | Most likely layer | Jump to |
|---|---|---|
| Command says "daemon not running" | Daemon | Daemon |
join <code> errors out or hangs | Pairing | Pairing failures |
Both online but members doesn't list each other | Discovery | Peer not appearing |
| Peer is visible but sync is slow / files stall | Transport | Stuck on relay / slow sync |
| You copy something and the peer gets nothing | Clipboard permission | Clipboard permissions |
| Search returns nothing or "index not ready" | Full-text index | Search & index |
| Phone can't reach the desktop / 401 / corrupt image | Mobile sync | Mobile 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 diffKey fields:
daemon.running— whether the process is alive.space.bound— whether the current profile is bound to a space.falsemeans you haven't rununiclip space initoruniclip space joinyet.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;nullmeans direct.peers[].reachability— per-peer reachability snapshot.membership_convergence— whether the active space is fully connected:complete,converging,waiting_for_upgrade, orblocked.
If daemon.running = false but uniclip service start fails, run
it in the foreground to capture the trace:
uniclip run -vRead 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 showsusing 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 failedwith 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.jsonin 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 appMinimal 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 sponsorDon'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:
-
Confirm clocks on both ends agree to within a few minutes. Argon2id and signature checks are sensitive to clock drift.
-
On the sponsor,
uniclip space status --json | grep handshakeshows whether it's waiting for a joiner. If nothing arrived, discovery itself is broken — jump to Peer not appearing. -
The default handshake TTL is roughly three minutes. After that the sponsor drops the invite and the joiner sees "invitation expired". Just
space inviteagain. -
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(networkfield) 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) andwlr-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/watchfeatures 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 statusreports 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 Nlets 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.
- 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.
- 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 onAuto, 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>touniclip mobile network set. - Check listener state.
uniclip mobile statusreportslan_listener_errorif the daemon tried to bind and failed (port in use, permission denied). Resolve the underlying error or pick a different port. - Firewall on the desktop OS. Confirm inbound traffic on port
42720(or your custom port) is allowed for the LAN profile. - Did you change the IP / port recently? A daemon restart is
required to apply listener changes; the Shortcut on the phone
also needs its
urlfield 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/passwordfields.
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:
- Restart the daemon so the listener rebinds.
- Update the Shortcut's
urlfield 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:
| Platform | Path |
|---|---|
| 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 -vWhen filing an issue, please attach:
uniclip --version, OS and version.uniclip space status --jsonfrom 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:
- 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.
- Type
RESETin the confirmation dialog and press Reset. - The app deletes the on-disk keyslot and KEK on this device, clears
SetupStatus, and drops you back at the setup screen. From there rununiclip space initfor a fresh space oruniclip space joinfrom 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.desktopAfter cleanup, uniclip space init or uniclip space join starts fresh. The
keyring's KEK entry will be overwritten by the next space init.
- Quit the GUI;
uniclip stop. - 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
.AppImagefile.
- macOS Homebrew:
- Delete the data directory (paths above).
- 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
seahorseorsecret-toolto wipe theuniclipboardnamespace.
- macOS Keychain: search
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.