Xray on Windows Server: Startup, Permissions, and Recovery

Xray on Windows Server: Startup, Permissions, and Recovery

Ryan Foster
October 11, 2026· 10 min read

Xray on Windows Server can start at boot under a restricted Task Scheduler account. Using Server 2022 x64 and Xray v26.3.27, this guide covers one VLESS/REALITY connection, failures, updates, and removal. These source-based instructions have not been tested end to end by the author.

Key Takeaways

  • The Xray executable is not a native Windows service; use one directly supervised scheduled task.
  • Keep the binary and configuration read-only to the runtime account, with a separate writable log directory.
  • Allow one trusted client's source address and one TCP port; preserve the independent management route.
  • A listening socket or successful configuration check does not prove authenticated proxy traffic.

When is Xray on Windows Server the right maintenance task?

Start with the ownership and recovery checklist. For an everyday exit, compare a VPS with a managed VPN before accepting Windows patching and credential maintenance. Scope: Windows lifecycle, excluding Linux installation and protocol design.

The roles of the Xray core and its clients explain why installing an executable does not configure a browser. Keep protocol, transport, and obfuscation layers distinct: VLESS, RAW transport, REALITY, and application proxy settings each have a separate role.

What must you prepare before changing the host?

Prepare an authorized, dedicated Server 2022 host, independent recovery console, and separate Windows client. The TLS 1.3 destination must be owned or authorized, with a valid certificate and matching name; otherwise stop. Do not blindly use an unrelated site's name.

Record current Windows Firewall profiles, inbound rules, listening ports, task names, and the management path. Verify a fresh management login through the recovery route. The device troubleshooting baseline helps separate client problems from server configuration.

Use TCP 24443; replace every uppercase placeholder below before running. SERVER_LISTEN_IP is an address assigned to the server, possibly its private address behind provider NAT. SERVER_ADDRESS is the client-reachable endpoint. TRUSTED_CLIENT_PUBLIC_IP is the source seen by the server, not the client's private LAN address.

Step 1: Install a fixed official package and set Xray Windows permissions

Download official v26.3.27 Xray-windows-64.zip through a browser with normal TLS verification. Extract to C:\Xray\bin; create C:\Xray\config and C:\Xray\logs. Avoid tutorial mirrors. Record the version; privately retain the preceding trusted package.[1]

In Computer Management, create local standard account XrayRunner with a unique password. Do not add it to Administrators. Grant “Log on as a batch job” through Local Security Policy; a domain policy can override this, so resolve policy ownership before continuing. Keep its password in the credential manager used by the operator, not a script.

From elevated PowerShell, restrict only this newly created tree; never apply these commands to a shared installation.

$svc = "$env:COMPUTERNAME\XrayRunner"
icacls C:\Xray /inheritance:r
icacls C:\Xray /grant:r '*S-1-5-18:(OI)(CI)F' '*S-1-5-32-544:(OI)(CI)F' "${svc}:(OI)(CI)RX" /T
icacls C:\Xray\logs /grant:r "${svc}:(OI)(CI)M" /T

The SIDs retain SYSTEM and Administrators. XrayRunner can read the binary/configuration and modify logs, but cannot replace its program or credentials. Inspect icacls and remove inappropriate explicit grants on this new tree; disabling inheritance does not delete them.

Step 2: Build and check one authenticated configuration

Run the version, UUID, and X25519 commands first. Save the UUID and private key privately. In this release, the client-facing X25519 value is labeled Password; it belongs in client realitySettings.password, not the server private-key field. Generate a random 16-character hexadecimal short ID with your password manager.[2][3]

C:\Xray\bin\xray.exe version
C:\Xray\bin\xray.exe uuid
C:\Xray\bin\xray.exe x25519
C:\Xray\bin\xray.exe run -test -config C:\Xray\config\server.json
C:\Xray\bin\xray.exe run -config C:\Xray\config\server.json

Save the configuration below as C:\Xray\config\server.json before running the last two commands. Replace both OWNED_TLS_NAME occurrences with the authorized name. This release uses clients and network; verify compatibility before substituting newer example fields.

{
  "log": {"error": "C:\\Xray\\logs\\error.log", "loglevel": "warning"},
  "inbounds": [{
    "listen": "SERVER_LISTEN_IP", "port": 24443, "protocol": "vless",
    "settings": {"clients": [{"id": "GENERATED_UUID", "flow": "xtls-rprx-vision"}], "decryption": "none"},
    "streamSettings": {
      "network": "raw", "security": "reality",
      "realitySettings": {
        "show": false, "target": "OWNED_TLS_NAME:443", "xver": 0,
        "serverNames": ["OWNED_TLS_NAME"],
        "privateKey": "GENERATED_PRIVATE_KEY", "shortIds": ["GENERATED_HEX_ID"]
      }
    }
  }],
  "outbounds": [{"protocol": "freedom", "tag": "direct"}]
}

Run the syntax check and foreground launch as XrayRunner, using Windows “Run as different user” for PowerShell. Successful administrator execution does not prove runtime access. Stop on invalid configuration, unreadable keys, or an occupied port. Close the foreground instance before registering the task.

Step 3: Configure Xray Windows startup without an interactive login

In elevated PowerShell, register the executable directly, with a working directory and absolute configuration path; avoid detached-child launchers. Password-based task logon supports startup without anyone signed in.[4]

$action = New-ScheduledTaskAction -Execute 'C:\Xray\bin\xray.exe' -Argument 'run -config C:\Xray\config\server.json' -WorkingDirectory 'C:\Xray'
$trigger = New-ScheduledTaskTrigger -AtStartup
$settings = New-ScheduledTaskSettingsSet -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) -MultipleInstances IgnoreNew -ExecutionTimeLimit ([TimeSpan]::Zero)
$cred = Get-Credential -UserName "$env:COMPUTERNAME\XrayRunner" -Message 'Task account'
Register-ScheduledTask -TaskName 'Xray-Lab' -Action $action -Trigger $trigger -Settings $settings -User $cred.UserName -Password $cred.GetNetworkCredential().Password -RunLevel Limited
Start-ScheduledTask -TaskName 'Xray-Lab'
Get-ScheduledTaskInfo -TaskName 'Xray-Lab'
Get-NetTCPConnection -State Listen -LocalPort 24443

The task retries at most three times at one-minute intervals, ignores duplicate starts, and has no execution time limit. It cannot recover every hang. Inspect the actual process and logs alongside task status and result.

Confirm the saved task uses XrayRunner, “Run whether user is logged on or not,” and limited privileges. Reboot only after the recovery console works. If a policy changes the account rights or password, update the stored task credentials and repeat non-login startup checks.

Step 4: Allow one client and prove the application path

Keep the firewall enabled and default unsolicited inbound traffic blocked. Inspect existing broad rules for this binary or port first: Windows allow rules are additive, so this new narrow rule cannot cancel another broad allow. The example assumes a legitimately classified Private interface; if the server uses Public, set that actual profile explicitly instead of relabeling the network.[5]

New-NetFirewallRule -Name 'Xray-Lab-TCP' -DisplayName 'Xray Lab TCP' -Direction Inbound -Action Allow -Protocol TCP -LocalPort 24443 -LocalAddress 'SERVER_LISTEN_IP' -RemoteAddress 'TRUSTED_CLIENT_PUBLIC_IP' -Program 'C:\Xray\bin\xray.exe' -Profile Private

Apply the same source/port restriction in any provider firewall. Do not expose RDP globally or change its rescue rule. Copy the same Xray release to the separate client, save this as client.json, and replace the matching connection values. The private key never leaves the server.

{
  "log": {"loglevel": "warning"},
  "inbounds": [{"listen": "127.0.0.1", "port": 1080, "protocol": "socks", "settings": {"auth": "noauth", "udp": false}}],
  "outbounds": [{
    "protocol": "vless",
    "settings": {"vnext": [{"address": "SERVER_ADDRESS", "port": 24443, "users": [{"id": "GENERATED_UUID", "encryption": "none", "flow": "xtls-rprx-vision"}]}]},
    "streamSettings": {
      "network": "raw", "security": "reality",
      "realitySettings": {"serverName": "OWNED_TLS_NAME", "fingerprint": "chrome", "password": "GENERATED_PUBLIC_VALUE", "shortId": "GENERATED_HEX_ID"}
    }
  }]
}

Run xray.exe run -test -config client.json, then xray.exe run -config client.json. In Firefox, manually select SOCKS5 at 127.0.0.1:1080 and enable proxy DNS for SOCKS5. Visit the request's visible exit IP, then the intended authorized HTTPS destination. That result covers this request, not every app, DNS path, IPv6 route, or UDP flow.

Use a temporary client copy to try a different UUID and an unapproved server name; neither may produce the intended authenticated proxy request. A TCP handshake or target-site fallback is not successful proxy authentication. Restore the correct client settings and compare server diagnostics without publishing logs or credentials.

How do you handle failures, updates, and retirement?

Reader checkExpected evidenceStop or recovery action
Runtime account cannot read configurationStartup fails; no intended proxy requestCorrect only the configuration ACL; never grant Administrator
Start task twiceOne intended Xray processInspect task action and duplicate tasks before reopening access
Process exits unexpectedlyAt most three one-minute retriesRead the error, disable the task if unresolved, repair offline
Reboot with nobody signed inCorrect account, listener, and authenticated requestRestore task credentials or previous known configuration
Allowed source changesOld source rule no longer permits the clientConfirm the new address, then narrowly update the owned rule

For an update, disable/stop this task, confirm its process and listener are gone, and privately back up the binary, configuration, ACL record, and exported task definition. Stage the new official package separately, inspect its release notes, validate under the runtime account, and repeat positive and negative client checks. If it fails, stop again and restore the preceding package/configuration pair before reopening access.

The operator must manage logs: inspect daily; at 10 MiB, disable/stop the task, privately archive error.log, retain at most seven archives, then restart and check the request. This interrupts service; Xray does not provide this rotation policy. Investigate rapid growth rather than deleting evidence.

To retire the lab, use the commands below, then clear Firefox's proxy, stop the client process, revoke provider rules and connection credentials, and remove XrayRunner only after confirming no other task uses it. If a listener remains, identify its owner rather than terminating all Xray processes.

Disable-ScheduledTask -TaskName 'Xray-Lab'
Stop-ScheduledTask -TaskName 'Xray-Lab'
Remove-NetFirewallRule -Name 'Xray-Lab-TCP'
Get-NetTCPConnection -State Listen -LocalPort 24443 -ErrorAction SilentlyContinue
Unregister-ScheduledTask -TaskName 'Xray-Lab' -Confirm:$true

Summary

  • Separate installation ownership from the low-privilege runtime account.
  • Validate configuration, task startup, source restrictions, and actual authenticated requests independently.
  • Keep the preceding package/configuration pair and a management route that survives failure.
  • Stop the owned task and revoke access before deleting its resources.

FAQ

Is Xray a native Windows service?

The standalone executable has no native service lifecycle. This procedure supervises it through Task Scheduler without an SCM wrapper.

Why use a separate account?

A restricted account limits what a compromised process can modify. It still needs read access to its configuration and write access to the dedicated log directory.

Does a successful configuration test prove connectivity?

A configuration test checks the loaded configuration, not the provider firewall, target certificate, client authentication, or an application's actual traffic path.

Why does the proxy fail only after reboot?

Check stored task credentials, batch-logon rights, working directory, and target reachability. Foreground success while an administrator is logged in does not verify those conditions.

Can the firewall rule restrict a roaming client?

The rule matches the source address visible at the server. If that address changes, verify and update the single authorized source rather than broadening access globally.

What does a failed REALITY client prove?

Failure with a wrong UUID or unapproved name supports rejection of that attempted proxy session. It does not require the underlying TCP port to refuse every handshake.

Can I reuse the instructions on another Windows version?

Recheck account policy, Task Scheduler behavior, firewall profile, and package support first. The documented baseline is Server 2022, not a tested matrix of Windows releases.

Disclaimer: Use only authorized infrastructure and comply with applicable rules. The guide was assembled from the official sources below and was not fully tested end to end on Windows Server.

Sources:

  1. Xray-core v26.3.27
  2. Xray v26.3.27 VLESS configuration
  3. Xray v26.3.27 transport configuration
  4. Microsoft Task Scheduler
  5. Microsoft Windows Firewall

Sources checked 11 October 2026.


Related Articles:

Start your 3-day free trial

Sign up to experience all premium features at no cost.

*Available only to new users. Each user is limited to one trial.

Xray on Windows Server: Startup, Permissions, and Recovery | AethoVPN