๐ Subscription page rebuilt, Xray that survives a bad config, AmneziaWG relay ports & large-fleet node sync
- ๐ Profile page no longer disclosed โ subscription responses stop advertising a link to the built-in profile page, and the page itself is now opt-in.
- ๐จ New subscription page โ usage ring, remaining quota, Subscription / Apps / Configs tabs, one-tap import on Android, iOS , and right-to-left rendering for Persian and Arabic.
- ๐ก๏ธ Xray stays up on a bad config โ a config the running core cannot bind is refused at the restart funnel with the reason shown in the panel, instead of killing every protocol in a one-second retry loop.
- ๐ก AmneziaWG relay ports fixed for good โ the loopback relay slot now wraps, survives disabled and peerless rows, and refuses a row its own port; on databases with a high inbound-id counter the protocol simply never worked before.
- ๐งต Large node fleets โ 32-way sync, pooled per-node HTTP clients, fanned-out fleet operations and no more node I/O inside the traffic writer.
- ๐ Reverse tunnels survive the panel โ a vless reverse client keeps its tunnel across edits, bulk enables, quota renewals and IP-limit cycles.
- ๐งญ DNS query type 0 repaired โ a stored
"qType": 0blocked every query through that outbound; a one-time migration fixes existing templates. - ๐งฐ Panel polish โ API docs split into tabs, clickable stat-card filtering on the Clients page.
โ ๏ธ Before you upgrade
Action required
- The built-in subscription profile page is now off by default (
subProfileMode=none), so theprofile-web-page-urlheader is no longer sent for installs that never set a custom URL โ do this: if your users rely on that page, open Settings โ Subscription and set the profile page mode to Built-in. A custom URL you already configured is kept and needs no action. Restart Xray After Client Disablenow also fires when a client is disabled or deleted by hand, not only when it is auto-disabled by expiry or quota โ do this: if you do not want a core restart on manual client edits, turn that setting off in Settings โ Xray.- Saving or enabling an inbound whose ports collide is now refused instead of silently taking the core down โ do this: if a save or enable is refused after upgrading, free the port named in the refusal; the refusal identifies the inbound row or AmneziaWG peer that owns it.
Automatic โ no action needed
- A one-time migration (
DNSOutboundQTypeZeroFix) rewrites a stored numeric"qType": 0in the DNS outbound to"0". Installs that reached 3.8.0 with a "block type 0" DNS rule had all DNS dropped through that outbound; this repairs the stored template in place. An unparseable template is logged and skipped โ the failure is not fatal and the panel still starts. - An existing
subProfileUrlis preserved and mapped to the new Custom mode, so no URL has to be re-entered. - Each node is now sent only the client IPs of the clients it hosts; the master stops pushing the whole fleet's IP table on every 10-second tick.
Requirements
Go 1.27.1 ยท Xray-core v26.9.9
๐ Security
- Subscription responses no longer hand out a link to the built-in profile page, which exposed the subscription URL itself; the page is now off unless enabled, with explicit None / Built-in / Custom modes in Subscription settings (#6538) @NgaiYeanCoi
- A node receives only the client IPs of the clients it hosts, instead of the entire fleet's IP table, so one node no longer holds records for clients served by every other node (
af466b6a)
๐ New
- The subscription page is rebuilt around a usage ring, remaining quota and a stats grid, split into Subscription / Apps / Configs tabs, with direct import on Android, iOS and Windows, a status that tells expired from depleted from disabled, and right-to-left rendering for Persian and Arabic (
e26cf1d3) - The API docs page separates WebSocket events from the Panel API into tabs and shows one API section at a time, keeping your authorization and try-it-out state across sections (
01ce2bce) - Clicking a summary card on the Clients page filters the list to that bucket, and each card's count now matches the size of its filtered list exactly (
5008906c)
โก Improved
- Node traffic sync runs up to 32 nodes at once instead of 8: a 300-node fleet's tick drops from 25โ30s to 6โ9.5s, so dashboard traffic, online clients and quota enforcement keep their intended cadence (
3c8cf357) - Each node keeps one pooled HTTP client instead of rebuilding it on every 5-second heartbeat, removing a full TCP+TLS handshake per node per tick (#6548) @BlindMaster24
- The Nodes table stops re-rendering every row when no node has changed โ about 390ms down to 0.5ms for 150 nodes (
3fa44915) - The Inbounds table rebuilds only the rows whose numbers actually moved on a websocket push, instead of every row on every push (
7fc86f87) - The row-count selector in the panel, Xray and AmneziaWG log modals is wide enough to read its larger values (
5fe4f241) - The IP-limit temporary disconnect is documented for what it actually does: it clears the core's stored credential so new connections are refused, while the fail2ban ban on the logged IP is what ends traffic already flowing (#6551) @BlindMaster24
๐ Fixed
Xray & inbounds
- Xray no longer exits into a one-second restart loop when a saved config's listens collide: the generated config is probed at the single restart funnel, the running core keeps serving, and the panel surfaces the reason instead of leaving it in the logs (#6547) @BlindMaster24
- Port conflicts are checked when an inbound is enabled and against ports an AmneziaWG peer forwards, not only when a row is saved; the refusal names the row or peer that owns the port (#6549, #6554) @BlindMaster24
- A DNS outbound rule set to query type 0 no longer matches every query โ the core drops a bare numeric
0, and a rule with no query types blocks, refuses or hijacks all DNS through that outbound (bc424f09) - Disabling or deleting a client ends its live session when restart-on-client-disable is enabled; dropping the credential alone left a disabled client's established connection passing traffic across vless, vmess, trojan and shadowsocks (#6550) @BlindMaster24
- A loopback or AmneziaWG outbound spelled with capitals is read the way the core reads it, so renaming or deleting the inbound it names keeps the tag in step and the outbound is still bridged instead of failing the core with "unknown config id" (#6530, #6531) @BlindMaster24
AmneziaWG
- An AmneziaWG inbound's loopback relay port is allocated and reserved correctly: the port window wraps instead of running out permanently once the inbound-id counter passes it, a disabled or peerless row keeps its slot, and a row is refused its own relay port โ each case previously put two listeners on one port and took every protocol on the host down with it (#6539, #6540, #6542, #6544) @BlindMaster24
Nodes
- A burst of node transitions sends one alert per direction naming the nodes, so a master-side network blip across 150 nodes no longer overruns the notifier queue and the Telegram and Discord rate limits (
56bb876d) - Reset-all-traffic, panel updates and bulk inbound deletes fan out across nodes instead of walking them one at a time: 15 hanging nodes out of 150 no longer keep a request running for 2m41s after the browser was already told it failed (
eb11e8c8) - A disabled, deleted or offline node no longer keeps its clients listed as online on the dashboard, or its learned sub-nodes on the Nodes page until the panel restarts (
a84bbeab) - A depleted client's node pushes run off the traffic writer, where one hanging node used to freeze traffic polls, node snapshot merges and every client edit for the whole wave (
ea66aa49) - The periodic traffic reset processes eight due inbounds and clients at a time, instead of stretching a single run over hours behind a few hanging nodes (
dea7cd9c) - LDAP sync enables, disables and detaches clients through the bulk paths, so each inbound is locked and pushed once per run rather than once per directory user (
3c1498d8) - Deleting a node frees its network metric history and its pooled HTTP client, which stayed in memory until the panel restarted (
bc49c1a6) - A node running on a different update channel than the master is no longer permanently tagged as having an update available (
14b92fbc)
Panel & clients
- A vless client carrying a reverse config keeps its tunnel across an edit, a bulk re-enable, a quota renewal, adding a client to an existing inbound, and an IP-limit disconnect cycle โ all of which left it able to connect but unable to open its tunnel until Xray restarted, with nothing logged (#6553, #6558) @BlindMaster24
- A 2FA code submitted at the end of its 30-second window, or with slight clock drift between client and server, is accepted instead of rejected as invalid (#6546) @sdhfsl
- A subscription outbound's tag stays bound to its server when the upstream rotates its reality shortId and SNI on every request; removing or inserting a server used to re-point existing tags at entirely different servers, breaking balancers and routing rules that select by tag (
c9e62451) - The Edit Client modal no longer shows a scrollbar when its fields already fit, and the bar is no longer painted light inside the dark modal (
e8bab17c)
Reports
New Contributors
Full Changelog: v3.8.0...v3.8.5