Skip to content

Image paste fails ("cannot connect: private key not found") — upload uses a revoked/old host pairing + local hostname instead of the active connection #3

Description

@dominikmartn

Summary

Pasting/sending an image from the iOS app fails with "cannot connect: private key not found", even though the normal terminal/SSH session works perfectly. The image upload (SCP, per /docs/image-paste) opens its own SSH connection that targets the host's local hostname (.local / link-local) and offers an old, revoked key from a previous Easy-Pair pairing — not the active connection's key. The image never leaves the phone.

Environment

  • Moshi iOS app: v3.5.0
  • moshi-hook: 0.2.26 (Homebrew tap rjyo/moshi)
  • Host: macOS (Apple Silicon), Remote Login (sshd) enabled
  • Transport: Tailscale. Host reachable at <machine>.tailXXXX.ts.net / 100.x.x.x. Terminal/SSH works flawlessly over Tailscale.

What happens

The host was re-paired over time; only the newest pairing is active (moshi-hook host list):

Pairing Host it points at Key fingerprint State
A (first) <machine>.local SHA256:p/1PZs3t… revoked (removed from authorized_keys)
B <machine>.ts.net SHA256:HjKecodm… revoked
C (current) <machine>.ts.net SHA256:AYs+pwuq… active (only key in authorized_keys)

macOS unified log (log show … process CONTAINS "sshd"), captured in the same minute as one image send:

Accepted publickey for <user> from 100.x.x.x port … ssh2: ED25519 SHA256:AYs+pwuq…   ← terminal: OK (Tailscale)
Connection closed by fe80::…%enX port … [preauth]                                     ← image upload: link-local
Connection closed by 169.254.x.x port … [preauth]                                     ← image upload: rejected

The terminal leg authenticates over Tailscale (100.x) with the active key C. The image-upload leg instead hits the link-local / .local address and is rejected at preauth because it offers the revoked pairing-A key (p/1PZs3t…), not the active key C.

Repro

  1. Easy-Pair a host → pairing A, hostname <machine>.local.
  2. Re-pair to a Tailscale address → pairing C (<machine>.ts.net); moshi-hook host revoke the old pairing A.
  3. Open the terminal → works over Tailscale (Accepted publickey … key C).
  4. Paste/send an image → "cannot connect: private key not found".

Expected

Image upload should use the currently selected/active connection (its host and key) — i.e., the same Tailscale connection the terminal uses — not a stale/revoked pairing or the auto-detected local hostname.

Notes

  • The phone keeps using pairing A for the upload path even after (a) deleting the old connection from the visible list (only the Tailscale connection is shown), (b) re-pairing the agent (moshi-hook pair), and (c) restarting the daemon. Nothing short of deleting + reinstalling the app appears to change which pairing the upload uses.
  • /docs/image-paste says the upload is SCP to the host, while the marketing copy says "a fetchable URL — no scp". The SCP-to-local-hostname behavior also means image paste only works on the same LAN as the host, never remotely. Routing the upload over the active connection's configured host would make it work over Tailscale too.

(Filed against moshi-skill as the active public repo — happy to move this if there's a better place for iOS-app bugs.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions