NVIDIA / NVIDIA/Personal-AI-Router

[Bug]: pairing fails after a correct PIN when the inviter connected over IPv6 link-local — the joiner's return POST drops the %zone ([fe80::…]:14321 → no route to host)

Aperta
#69 0 commenti 0 reazioni 1 assegnatario Vedi su GitHub

@ckelseynv ci sta già lavorando.

Dal 18/9/2026.

Lingua principale
Go
Stelle
1.4k
Fork
250
Merge medio
23h 27m
PR unite (30g)
1

Descrizione

PAIR version

v0.1.1 (13b6811), all 14 services built from source with Go 1.25.5 (darwin/arm64); same behaviour expected from the release binaries (the code path is services/nvpair-cluster-manager/invite.go).

Operating system

macOS 26.5.2 on both nodes (inviter and joiner).

Hardware

Two Apple Mac mini M4 (16 GB) on one Wi-Fi LAN, IPv4 192.168.86.0/24 plus IPv6 link-local on en0.

Inference engine and model

Ollama 0.30.7 on the joiner (llama3.2:1b); not relevant to the bug.

What happened

cluster:invite-node {"address":"karen.local"} from the inviter returned a PIN and state:"pending"; the joiner received cluster:invite-received and answered cluster:respond-to-invite {inviteId, accept:true, pin} with the correct PIN — and the result was state:"failed". The joiner's log shows why: its completion/notify POST to the inviter used the inviter's IPv6 link-local address without the zone:

[nvpair-cluster-manager] INFO invite inv-9f69cc176d6c: completion failed: Post "http://[fe80::c16:bee4:c6a1:3fd]:14321/v1/cluster/pairing": dial tcp [fe80::c16:bee4:c6a1:3fd]:14321: connect: no route to host
[nvpair-cluster-manager] INFO invite inv-9f69cc176d6c: notify inviter fail attempt 1/3: ... (same, ×3)

fe80::/10 addresses are only routable with a scope (%en0); the inviter had reached the joiner over link-local (the hostname resolved to an IPv6 link-local first), the joiner took the remote address of that inbound connection as the inviter's address, and the zone was dropped when it was rendered back into a URL. Both nodes' /v1/cluster/pairing were reachable over IPv4 the whole time.

Expected

Either keep the zone when rendering a link-local address into the return URL ([fe80::…%25en0]), or prefer a global/IPv4 address from the inviter's advertised ips= list for the return path; at minimum surface the dial error in the respond-to-invite result instead of a bare state:"failed" after a correct PIN.

Steps to reproduce
  1. Two macOS nodes on one LAN with IPv6 link-local enabled (default), PAIR services running on both.
  2. On node A: {"jsonrpc":"2.0","id":1,"method":"cluster:invite-node","params":{"address":"<node-B-hostname>.local"}} — where the name resolves to a link-local IPv6 first (as karen.local did here: fe80::… then 192.168.86.17).
  3. On node B: answer cluster:invite-received with cluster:respond-to-invite and the PIN shown on A.
  4. Observe state:"failed" and the log line above on B.
  5. Repeat with "address":"192.168.86.17" (IPv4 literal): state:"paired", nodes:get-initial shows two members on both sides.
Sanitized logs

Above; nothing else in either log around the failure. Happy to attach the full sanitizer bundle if useful.

Confirmations
  • I searched existing issues (#1 mDNS source port, #3 Local Network permission, #44 multicast drops are adjacent; none covers the pairing return URL).
  • I agree to follow the Code of Conduct.

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.