Skip to content

fix: surface the broker's Authorization Violation from subscribe() - #10

Merged
sujal-maheshwari2004 merged 2 commits into
mainfrom
fix/6-nats-auth-error
Oct 18, 2026
Merged

sujal-maheshwari2004 merged 2 commits into
mainfrom
fix/6-nats-auth-error

Conversation

@sujal-maheshwari2004

Copy link
Copy Markdown
Contributor

What was wrong

subscribe() with a wrong NATS token rejected with a generic TIMEOUT after about 20 s.

The broker does answer at once: -ERR 'Authorization Violation', then closes. But nats.js writes CONNECT and PING as two separate writes. The broker closes after reading CONNECT, the late PING lands on a closed socket, the kernel answers with a TCP reset, and the client never reads the -ERR (it sees ECONNRESET). It then retries until its 20 s connect timeout. Checked at the protocol level against priompt v0.7.2's embedded broker: CONNECT+PING in one write gets the -ERR every time (8/8); split writes get ECONNRESET.

Fix

subscribe() first runs the handshake once by hand (checkNatsAuth), with CONNECT and PING in a single write, so the broker reads both and its -ERR arrives. A -ERR rejects immediately:

Error: NATS broker rejected the connection: Authorization Violation (check natsToken or the token in natsUrl)

Anything else (a PONG, a TLS broker, a network error) falls through to the normal nats.js connect, unchanged. The cost is one short extra TCP round trip per subscribe().

The repo had no test suite, so this adds npm test (node --test) with a small in-process NATS broker (test/fake-nats.js), and CI runs it. With lossyAuthErr the fake reproduces what nats.js sees from the real broker: a reset with no -ERR.

Test evidence

Regression test before the fix (main's client.js):

✖ subscribe with a wrong NATS token rejects promptly with the authorization error (5043ms)
✔ subscribe with the right NATS token still delivers events
ℹ pass 1
ℹ fail 1

After:

$ npm test
✔ subscribe with a wrong NATS token rejects promptly with the authorization error (105ms)
✔ subscribe with the right NATS token still delivers events (26ms)
ℹ pass 2
ℹ fail 0

Real run against priompt v0.7.2 serve -nats-token natssecret (Windows, nats://wrong@127.0.0.1:48222):

== main
subscribe rejected after 20.1s: NatsError: TIMEOUT TIMEOUT
== this branch
subscribe rejected after 0.0s: Error:  NATS broker rejected the connection: Authorization Violation (check natsToken or the token in natsUrl)
== this branch, right token (subscribe, then publish over gRPC)
published {"version_hash":"7ff08abf13404fee94ffefd6d148183a8bea7f857dde4c7e69376324583f9aef"}
event 7ff08abf1340 "structural"

A missing token (nats://127.0.0.1:48222 against a token-protected broker) now gives the same immediate error. Before, it timed out.

Expected conflict with #9

#9 (replace nats with @nats-io/transport-node) is independent of this PR. Both branch from main and both add the test harness. Whichever merges second needs a small rebase:

  • client.js: the require(...) line next to the new await checkNatsAuth(...). Keep both: the check does not depend on the NATS client package. I also ran it against fix: replace deprecated nats package with @nats-io/transport-node #9's @nats-io/transport-node v3, which loses the -ERR the same way.
  • test/fake-nats.js (add/add): keep this PR's version, which adds lossyAuthErr.
  • package.json scripts.test and .github/workflows/test.yml: identical lines.

Fixes #6

🤖 Generated with Claude Code

nats.js writes CONNECT and PING separately. When the broker rejects the
token it answers -ERR and closes before reading the PING; the late PING
draws a TCP reset, the client never reads the -ERR, and it retries until a
generic TIMEOUT about 20 s later.

subscribe() now runs the handshake once by hand with CONNECT and PING in a
single write, so the broker's -ERR arrives, and rejects with it
immediately. Anything other than a -ERR is left to the real connect.

Adds an npm test suite (node:test) with a small in-process NATS broker
and runs it in CI.

Fixes #6

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sujal-maheshwari2004
sujal-maheshwari2004 merged commit ba00dbb into main Oct 18, 2026
1 check passed
@sujal-maheshwari2004
sujal-maheshwari2004 deleted the fix/6-nats-auth-error branch October 18, 2026 18:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

subscribe() with a wrong NATS token rejects with TIMEOUT after ~20 s

1 participant