Introduction
When Xray is installed into a non-standard directory (e.g., /data/xray via the jfrog_home variable), SELinux in Enforcing mode might block the service from starting. The systemd service fails with something as shown below:
xray.service: Failed at step EXEC spawning /data/xray/app/bin/xrayManage.sh
=> Failed to start JFrog Xray Service
Switching SELinux to Permissive mode resolves it, confirming SELinux as the cause.
Why This Happens
Files installed into non-standard paths inherit a generic default_t SELinux context. This context does not allow systemd to execute binaries, so the Xray service startup is denied. We can check the label using the following command:
$ ls -laZ
-rwxr-xr-x. 1 xray xray unconfined_u:object_r:default_t:s0 3234 Jan 29 10:21 /data/xray/app/bin/xrayManage.sh
Note: The Xray Linux Archive installer and its Ansible role do not currently manage host-level SELinux policies. These steps must be applied by the system administrator.
Resolution
Step 1: Relabel the Xray directories
Apply the correct SELinux file contexts and refresh the labels (assuming the xray folder is under “/data” directory):
sudo semanage fcontext -a -t bin_t "/data/xray/app/bin(/.*)?"
sudo semanage fcontext -a -t var_log_t "/data/xray/var(/.*)?"
sudo restorecon -Rv /data/xray
Verify that the labels were updated correctly. It should show bin_t, not default_t:
$ ls -laZ /data/xray/app/bin/xrayManage.sh
-rwxr-xr-x. 1 xray xray unconfined_u:object_r:bin_t:s0 3234 Jan 29 10:21 /data/xray/app/bin/xrayManage.sh
Now start the service:
sudo systemctl start xray
The service should start now. However, if systemd still fails with a denial related to /etc/shadow access, continue to Step 2.
Step 2: Resolve shadow file access denial (host-hardened environments only)
On hosts with additional security hardening, systemd may be blocked from reading /etc/shadow when validating the Xray service user. The audit log might show denials with init_t accessing shadow_t.
Capture the denial and generate a targeted policy module:
sudo ausearch -m AVC -ts recent | grep shadow > xray_deny.log
cat xray_deny.log | audit2allow -M xray_shadow
sudo semodule -i xray_shadow.pp
Start the service again:
sudo systemctl start xray
The Xray service should be up and running:
[xray@jfrog-test-xray bin]$ ./xray.sh status
2026-03-02T12:05:06.529Z [shell] [INFO ] [] [installerCommon.sh:3601 ] [main] - Setting JF_SHARED_NODE_ID to jfrog-test-xray
2026-03-02T12:05:06.604Z [shell] [INFO ] [] [installerCommon.sh:3606 ] [main] - Found explicit shared.node.ip in system.yaml with value : x.x.x.x
2026-03-02T12:05:06.712Z [shell] [INFO ] [] [installerCommon.sh:3601 ] [main] - Setting JF_SHARED_NODE_NAME to jfrog-test-xray
========================
JF Environment variables
========================
JF_SHARED_NODE_ID : jfrog-test-xray
JF_SHARED_NODE_IP : x.x.x.x
JF_SYSTEM_YAML : /data/xray/var/etc/system.yaml
JF_PRODUCT_RABBITMQ_HOME : /data/xray/app/third-party/rabbitmq
JF_PRODUCT_HOME : /data/xray
JF_SHARED_NODE_NAME : jfrog-test-xray
2026-03-02T12:05:07.776Z [shell] [INFO ] [] [systemYamlHelper.sh:673 ] [main] - Resolved JF_SHARED_NODE_NAME (jfrog-test-xray) from environment variable
2026-03-02T12:05:08.632Z [shell] [INFO ] [] [manageRabbitmq.sh:124 ] [main] - Rabbitmq is running
server is running (PID: 145600)
persist is running (PID: 145804)
analysis is running (PID: 146010)
indexer is running (PID: 146228)
sbom is running (PID: 146440)
policyenforcer is running (PID: 146640)
Using default router's certificate and private key
router is running (PID: 146768)
observability is running (PID: 146891)