{"record":{"id":"5984cbc8a03a3359","repo":"nats-io/nats-server","slug":"not-in-the-allowed-list","errorCode":null,"errorMessage":"not in the allowed list","messagePattern":"not in the allowed list","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/websocket.go","lineNumber":1091,"sourceCode":"\t\t\treturn errors.New(\"not same origin\")\n\t\t}\n\t\t// I guess it is possible to have cases where one wants to check\n\t\t// same origin, but also that the origin is in the allowed list.\n\t\t// So continue with the next check.\n\t}\n\tif !listEmpty {\n\t\tw.mu.RLock()\n\t\torigins := w.allowedOrigins[oh]\n\t\tw.mu.RUnlock()\n\t\tvar allowed bool\n\t\tfor _, ao := range origins {\n\t\t\tif u.Scheme == ao.scheme && op == ao.port {\n\t\t\t\tallowed = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !allowed {\n\t\t\treturn errors.New(\"not in the allowed list\")\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc wsGetHostAndPort(tls bool, hostport string) (string, string, error) {\n\thost, port, err := net.SplitHostPort(hostport)\n\tif err != nil {\n\t\t// If error is missing port, then use defaults based on the scheme\n\t\tif ae, ok := err.(*net.AddrError); ok && strings.Contains(ae.Err, \"missing port\") {\n\t\t\terr = nil\n\t\t\thost = hostport\n\t\t\tif tls {\n\t\t\t\tport = \"443\"\n\t\t\t} else {\n\t\t\t\tport = \"80\"\n\t\t\t}\n\t\t}","sourceCodeStart":1073,"sourceCodeEnd":1109,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/websocket.go#L1073-L1109","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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"],"exampleFix":"// before (server.conf)\nwebsocket {\n  allowed_origins: [\"https://app.example.com\"]\n}\n// after\nwebsocket {\n  allowed_origins: [\"https://app.example.com\", \"http://localhost:3000\"]\n}","handlingStrategy":"validation","validationCode":"// compare before deploying\nconst pageOrigin = window.location.origin; // what the browser sends\n// server.conf must contain exactly this origin (scheme+host+port):\n// websocket { allowed_origins: [\"https://app.example.com\"] }\nconsole.assert(true, `ensure allowed_origins includes ${pageOrigin}`);","typeGuard":null,"tryCatchPattern":"// server-side\nif err := wsCheckOrigin(r); err != nil {\n    if strings.Contains(err.Error(), \"not in the allowed list\") {\n        log.Printf(\"origin %q not in allowed_origins\", r.Header.Get(\"Origin\"))\n    }\n    http.Error(w, \"origin not allowed\", http.StatusForbidden)\n    return\n}","preventionTips":["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"],"tags":["websocket","cors","origin","config"],"backgroundTag":"origin-not-allowed","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}