DisplaySync

Sign won't claim

Symptom: the kiosk is showing the QR claim screen and you've scanned it from the mobile app, but the claim isn't completing — either the mobile app reports an error, or the kiosk never transitions out of the QR screen.

This page walks the diagnostic path in the order that matches what's actually broken most often: backend reachability first, then identity/state issues, then weirder edge cases.

Quick diagnostic

Open the Status Dashboard on the kiosk: keyboard shortcut Ctrl+Shift+S. The overlay shows the kiosk's view of its own state. The first thing to check:

  • Connection Status: Connected — the kiosk reaches the backend
  • Sign ID: <a UUID> — identity is initialized
  • Backend URL: https://api.displaysync.live (or your env's URL) — pointed at the right place

If any of these are wrong, the rest of this page is your fix path. If all three look healthy and the claim still fails, jump to The QR scans but dashboard rejects the claim.

The kiosk shows "Disconnected"

The QR screen rendered, but the kiosk hasn't established a WebSocket session — there's nothing to claim against.

Diagnose:

# From the kiosk (RDP/VNC or local keyboard):
Test-NetConnection api.displaysync.live -Port 443

# Inspect logs for connection errors
Get-Content "C:\ProgramData\DisplaySync\logs\sign.log" -Tail 50 |
  Select-String "WebSocket|ECONNREFUSED|connect"

# Or tail error.log for ERROR-level lines only — faster for handshake errors
Get-Content "C:\ProgramData\DisplaySync\logs\error.log" -Tail 50

# Tail the live log during a fresh claim attempt
Get-Content "$env:ProgramData\DisplaySync\logs\sign.log" -Wait -Tail 20

For the full path map, see File locations.

Common causes:

Symptom in logsCauseFix
ECONNREFUSED / ENETUNREACHVenue firewall blocks 443 outboundAllowlist api.displaysync.live (see Network requirements)
Hostname not foundDNS issueCheck the venue's DHCP-assigned DNS, or set the kiosk to public DNS (1.1.1.1, 8.8.8.8)
certificate has expiredKiosk clock is wrongNTP misconfigured — see Network requirements → DHCP, DNS, NTP
WebSocket error: Unexpected server response: 502Backend transient failureWait 30 seconds and retry. If persistent, check status page

If the kiosk is on Wi-Fi and showing intermittent connect/disconnect cycles, the venue Wi-Fi may have a captive portal that's interfering. See Network resilience.

The kiosk shows "Connected" but the dashboard doesn't see it

This means the WebSocket is up, but the kiosk hasn't successfully registered as a sign in your org's view.

The desktop sign emits sign:register on connect. If the backend can't match the kiosk's signId and macAddress to anything, it stores the kiosk under a Redis key (PENDING_SIGN_PREFIX = 'ws:pending-sign:', 24-hour TTL via PENDING_SIGN_TTL = 86400) keyed by short code. That's what makes the kiosk show up under Unclaimed Signs in the dashboard. Pending sign records survive backend restarts.

Diagnose:

  1. Confirm you're looking at the right org/event. If you have multiple orgs and switch back and forth, an unclaimed sign only appears under the org that holds the backend's WebSocket session — which is whichever org you most recently signed into. Sign out and sign in to the right org.

  2. Confirm the short code matches. The QR encodes signId + shortCode; the dashboard's Unclaimed Signs table shows the short code. They should match. If they don't, the kiosk regenerated identity since last reboot — see Stale identity below.

  3. Look at the kiosk log for sign:register events:

    Get-Content "C:\ProgramData\DisplaySync\logs\sign.log" -Tail 200 |
      Select-String "sign:register|registered|sign:error"
    

    You should see a sign:register followed by a sign:registered response with status: 'pending'. If you see sign:error instead, the message will tell you why.

The QR scans but dashboard rejects the claim

The mobile app scanned cleanly, the kiosk is in Pending, but the claim API call comes back with an error.

Mobile app messageHTTPCauseFix
"This device is already claimed"409This signId is in another org or event alreadySee The claim fails with "already claimed" below
"Short code does not match device ID"400Manual short-code entry typo'd, or the kiosk regenerated identityRe-scan the QR (don't manually enter); if mismatch persists, stale identity
"Insufficient permissions" / "Insufficient event permissions"403The user signed into the mobile app doesn't have a manager role on the target eventAsk the event owner to grant Manager role; see Roles & permissions
"Sign didn't respond. Check it's online and retry." (device_no_ack)504Handshake: kiosk failed to ack within timeoutVerify the kiosk shows "Connected" on Ctrl+Shift+S; reboot the sign app and retry
"Sign couldn't load the page." (device_load_failed)400Handshake: kiosk acked but URL load failedOpen the assigned URL from a venue laptop — if it doesn't load there either, the URL or venue network is the problem, not the sign
"Sign isn't connected." (sign_not_connected)400Handshake: no active WebSocket session for the signPower-cycle the kiosk; check the venue's outbound 443
"Another claim is in progress." (request_in_progress)409Handshake: a prior claim attempt is still in flightWait 30s and retry — Redis lock auto-releases

The claim fails with "already claimed"

This sign was previously claimed (by you or someone else). Two paths:

If you control the prior claim

  1. Dashboard: find the existing claim — the easiest way is to search the org-wide Signs view by short code.
  2. Open that sign's detail page → Settings → Unregister.
  3. The kiosk receives sign:unregistered, clears its local org/event state, and returns to the QR screen with a fresh-feeling identity.
  4. Re-scan from the mobile app and claim to the right event.

If a hardware swap is in play

If the device was previously claimed but a NIC has been replaced (or the storage was reimaged from a captured image), the kiosk's local data may have been wiped while the dashboard still shows the old record. From the dashboard:

  • Unregister the stale sign record.
  • The new device will appear as a fresh Unclaimed entry — claim it normally.

See Claiming signs → Replacement hardware for the full hardware-swap workflow.

If a clone collision is in play

Two cloned kiosks with the same signId can't both be claimed — only the first successfully registers. The desktop sign's clone-detection logic (compares stored MAC against current NICs on every boot) catches this on the second clone:

  • Stored MAC matches no current interface → identity gets cleared
  • Sign reboots into "fresh" state with new signId
  • Now claimable normally

If clone collisions are happening repeatedly, the image wasn't cleaned before Sysprep — see Capturing the image → Clean before Sysprep.

Pre-Sysprep state leakage: if the image was captured after a kiosk linked to an event but before the clean-state Sysprep checkpoint, two kiosks deployed from that image will boot with overlapping signId on first boot. Diagnostic: the dashboard shows two heartbeating signs claiming the same identity; one ejects the other within seconds. Fix: recapture from the clean post-Sysprep checkpoint. The clone-detection logic above handles the boot-side gracefully, but the dashboard record state needs operator cleanup.

Stuck on QR setup screen after a claim attempt

The mobile app says claim succeeded, but the kiosk is still showing the QR screen. Decision tree based on whether the Sign row exists in the dashboard:

What you see in the dashboardWhat probably happenedFix
Sign row exists with a status (online/offline/etc.)Pre-handshake bug or post-handshake apply-link broadcast dropped. The backend committed the claim but the kiosk never got the sign:apply_link event with the URL to load.Reboot the kiosk. On next boot, the kiosk's sign:register carries no local org info, the backend matches by signId to the existing claimed record, and re-emits the claim payload. See the Edge case below for the pre-handshake variant.
No Sign rowHandshake rejected the claim (acknowledged flow). Either the URL failed to load, or the kiosk didn't ack in time.Re-attempt the claim from mobile. See Operations → Claiming signs → How a claim is committed for the handshake flow and the structured error codes (Error codes → Sign claim & registration).

The dashboard-presence check is the fastest disambiguator — it tells you which side rolled back.

Edge case: claim "succeeded" but kiosk still shows QR

This is rare but worth knowing about. The mobile app got a 201 Created from the backend, but the kiosk never transitioned out of the QR screen.

Cause: the sign:claimed event from backend → kiosk got lost. The dashboard side is fine; the kiosk-side write didn't happen.

Fix: reboot the kiosk. On next boot:

  • The kiosk's sign:register carries no local org info (because the claim never wrote to disk)
  • The backend matches the kiosk's signId to the existing claimed Sign record
  • It re-emits the claim payload (sign:claimed)
  • The kiosk writes it locally and loads the assigned URL

If this happens repeatedly across reboots, the kiosk's APPDATA folder is read-only — see Kiosk won't start for permission fixes.

Last-resort: Ctrl+Shift+C URL override

If the dashboard's claim form isn't working but the kiosk reaches the backend (Ctrl+Shift+S shows Connected), a tech with keyboard access can use the config overlay to point the kiosk at a known-good backend URL or load a specific content URL directly:

  1. At the kiosk, press Ctrl+Shift+C. (PIN-prompts if a PIN is set — see Hotkeys → Ctrl+Shift+C.)
  2. In the Display URL field, paste the URL you want loaded.
  3. Click outside the field; the URL is saved to sign-config.json (see File locations) and loaded immediately.

This won't claim the sign — it just changes the URL the unclaimed kiosk is showing. Useful when you need a sign on the wall now and the claim path is broken; you can claim properly later.

Last-resort: full kiosk reset

When nothing above works and you just need this device claimed before doors open:

# Stop the sign app
Stop-Process -Name "DisplaySync Sign" -Force

# Wipe identity + cache (machine-wide data root)
Remove-Item "C:\ProgramData\DisplaySync" -Recurse -Force -ErrorAction SilentlyContinue

# Restart the sign app (or just reboot the device)
Start-Process "C:\Program Files\DisplaySync Sign\DisplaySync Sign.exe"

The kiosk regenerates a fresh signId and short code, the QR screen reappears with new content, and you can claim normally.

This is what the USB recovery drive does in script form for in-field cases where you can't easily get hands-on the device.

Still stuck

If you've worked through the above and the sign still won't claim, capture the diagnostics described in Getting support and reach out. Specifically:

  • The kiosk's last 500 lines of sign.log
  • A screenshot of the kiosk's Status Dashboard (Ctrl+Shift+S)
  • The dashboard's view of the org-wide Signs list filtered to status: pending
  • The exact mobile-app error message and the timestamp it occurred