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

  1. Add the browser page's exact origin (scheme://host:port) to websocket { allowed_origins } in the server config
  2. Remember browsers send the port for non-default ports — configure e.g. http://localhost:3000, not just http://localhost
  3. Match the scheme: an https page cannot connect when only http origin is allowed
  4. 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

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


AI-assisted analysis of nats-io/nats-server@3a66a489d2 (2026-09-02). Data as JSON: /api/errors/5984cbc8a03a3359. Report an issue: GitHub.