Skip to content

Server rejects every primary_username publish, so no user can have a .q name #240

Description

@lamat1111

Note on provenance: this report and the underlying research were produced with AI agents

This needs someone with server access. No client change can work around it, and both apps are otherwise finished and waiting on it.

A primary QNS name is meant to replace a user's display name everywhere. It has never worked end to end in production for anyone, because the server refuses to accept one.

The error

POST /users/:addr/public-profile carrying a primary_username returns:

HTTP 400
qns primary username failed validation: qns lookup: Get "./": stopped after 10 redirects

The identical request without the field succeeds.

It is a configuration fault, not a rejected claim

The natural reading is that the server checked the claim and found it wanting. It did not — it never reached QNS.

Two publishes from the same account, seconds apart, differing only in the name:

name sent resolves on QNS? result
gatto no — /resolve/gatto is 404 HTTP 400, error above
lamat yes — resolves, to a different address HTTP 400, byte-identical error

A working ownership check has to tell those two apart. It does not, so the failure happens before the name is considered.

Get "./" is a Go HTTP client error on a relative URL: the QNS base URL the lookup is built from is empty or malformed, so the request resolves against itself and loops until the redirect limit.

So the validation can never pass, for any name, for any user, however legitimately they own it.

What this explains

  • An account that genuinely owns a registered name, with a public profile, has no primary_username in its published record — only bio, display_name, profile_image, signature, timestamp.
  • The QNS primary-name tier, the rung that outranks a display name everywhere, has never once worked in production.

What is NOT broken

Stated because it narrows the fix:

  • The v2 signing payload is fine — this is a 400 from the validation step with an explicit message, not a signature failure.
  • Publishing without a name works — measured the same minute, a profile went 404 → 200 on a publish carrying no primary_username.
  • Un-electing works — it omits the field, taking the v1 route, which is accepted.
  • The clients are not at fault — the request is signed and sent correctly. This is the server's own outbound request failing.

The work needed

  • Fix the QNS base URL used during primary-username validation. Confirmed by a publish carrying a legitimately owned name returning 200.
  • A publish carrying a name the account does not own should be refused with an error naming the actual reason.
  • Re-measure: GET /users/:addr/public-profile shows primary_username.

Questions

  1. What is the validation meant to check — that the name resolves to the publishing address, or only that it exists?
  2. Is the QNS base URL an env var that is unset in this deployment?
  3. Should primary_username be inside canonicalize, so a stale relay cannot strip it? Today it is covered by the v2 payload but is not part of the canonical signed profile fields shared with the space wire.

Client status, for context

Both apps are done and waiting. Mobile resolves and renders a .q on every name surface; desktop is at parity on the security-relevant parts. A name ending in .q can no longer forge the verified marker on either client (enforced in quorum-shared).

Worth noting the server's intent is good news: nothing in either client currently verifies that a claimed primary_username resolves back to the claimant, so a name transferred away but still elected locally would let two accounts render as the same .q. Once this lookup works, the server refuses that. Receiver-side verification is planned on the clients as defence in depth, but the server check is the stronger line.

Measured against api.quorummessenger.com on 2026-08-06 from a mobile dev build.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions