nats-io/nats-server · error
not in the allowed list
Error message
not in the allowed list
What it means
During websocket origin checking, if the request's Origin is not in the configured AllowedOrigins list (and no same-origin match applies), the server rejects the upgrade with "not in the allowed list". This enforces the server's explicit CORS allow-list for websocket clients.
Source
Thrown at server/websocket.go:1091
return errors.New("not same origin")
}
// I guess it is possible to have cases where one wants to check
// same origin, but also that the origin is in the allowed list.
// So continue with the next check.
}
if !listEmpty {
w.mu.RLock()
origins := w.allowedOrigins[oh]
w.mu.RUnlock()
var allowed bool
for _, ao := range origins {
if u.Scheme == ao.scheme && op == ao.port {
allowed = true
break
}
}
if !allowed {
return errors.New("not in the allowed list")
}
}
return nil
}
func wsGetHostAndPort(tls bool, hostport string) (string, string, error) {
host, port, err := net.SplitHostPort(hostport)
if err != nil {
// If error is missing port, then use defaults based on the scheme
if ae, ok := err.(*net.AddrError); ok && strings.Contains(ae.Err, "missing port") {
err = nil
host = hostport
if tls {
port = "443"
} else {
port = "80"
}
}View on GitHub (pinned to 3a66a489d2)
Solutions
- Add the browser page's exact origin (scheme://host:port) to websocket { allowed_origins } in the server config
- Remember browsers send the port for non-default ports — configure e.g. http://localhost:3000, not just http://localhost
- Match the scheme: an https page cannot connect when only http origin is allowed
- As a last resort use allowed_origins to include a wildcard entry if your security model permits
Example fix
// before (server.conf)
websocket {
allowed_origins: ["https://app.example.com"]
}
// after
websocket {
allowed_origins: ["https://app.example.com", "http://localhost:3000"]
} Defensive patterns
Strategy: validation
Validate before calling
// compare before deploying
const pageOrigin = window.location.origin; // what the browser sends
// server.conf must contain exactly this origin (scheme+host+port):
// websocket { allowed_origins: ["https://app.example.com"] }
console.assert(true, `ensure allowed_origins includes ${pageOrigin}`); Try / catch
// server-side
if err := wsCheckOrigin(r); err != nil {
if strings.Contains(err.Error(), "not in the allowed list") {
log.Printf("origin %q not in allowed_origins", r.Header.Get("Origin"))
}
http.Error(w, "origin not allowed", http.StatusForbidden)
return
} Prevention
- Add every frontend deployment domain (including ports) to allowed_origins
- Remember browsers include non-default ports in Origin
- Automate config generation per environment so origins stay in sync
- Test websocket connections from each deployed frontend origin
When it happens
Trigger: A websocket client connects with an Origin header that does not match any entry in websocket { allowed_origins: [...] } in the server config; the origin's scheme or port differs from every configured allowed origin.
Common situations: Browser apps served from localhost:3000 connecting to a server that allows only https://app.example.com; adding a new deployment domain without updating allowed_origins; port mismatch (allowed origin lacks the explicit port the browser sends).
Related errors
- not same origin
- websocket requires TLS configuration
- MQTT clients over websocket must connect to the Websocket po
- mqtt authentication token not compatible with presence of us
- ack wait must be a positive value
AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02).
Data as JSON: /api/errors/5984cbc8a03a3359.
Report an issue: GitHub.