[GH-ISSUE #20] auto-imported config never starts: outbound_config field left empty by install.sh #14

Open
opened 2026-10-31 21:01:47 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @tqb333 on GitHub (Aug 1, 2026).
Original GitHub issue: https://github.com/MrTheory/os-xray/issues/20

install.sh auto-import (import_existing_config()) populates wizard display fields but not outbound_config, so the imported instance fails to start

Environment: OPNsense 26.7.1 (FreeBSD 15.1 amd64), os-xray v3.0.0, tun2socks v2.7.0, xray-core v26.3.27

Description

When install.sh detects a pre-existing xray-core/tun2socks config on disk (detect_existing()) and imports it (import_existing_config()), it writes individual instance fields to config.xml: server_address, server_port, vless_uuid, flow, reality_sni, reality_pubkey, reality_shortid, reality_fingerprint, socks5_port, tun_interface, mtu, config_mode=wizard. These display correctly in the GUI's Instance tab afterward.

However, xray-service-control.php's xray_write_config() builds the actual runtime outbound block entirely from a separate field, outbound_config (a serialized JSON string of the full Xray outbound object — protocol/settings/streamSettings) — a field import_existing_config() never writes. Presumably this field is normally populated by the GUI controller's own save/serialize logic when a user submits the Instance form, which the CLI import path bypasses entirely.

Result: starting an auto-imported instance fails silently from the user's point of view:

ERROR: outbound_config is empty
ERROR: config file not found after write: /usr/local/etc/xray-core/config-<uuid>.json

even though every field looks correctly populated in the GUI.

Steps to reproduce

  1. Manually place a valid xray-core config.json (vless+reality outbound) at /usr/local/etc/xray-core/config.json and a matching tun2socks config.yaml at /usr/local/tun2socks/config.yaml before running install.sh on a fresh install.
  2. Run install.sh — it correctly detects and reports the existing config ([FOUND] Existing xray/tun2socks config detected: ...), and the GUI Instance tab shows all fields populated.
  3. Try to start the instance — it fails as above.

Workaround that confirms root cause

Manually adding <outbound_config>{"protocol":"vless","settings":{...},"streamSettings":{...}}</outbound_config> (the same object as config.json's outbounds[0]) directly to the instance in config.xml makes the instance start immediately, with no other changes.

Suggested fix

Either have import_existing_config() also construct and write outbound_config from the detected values (mirroring whatever the GUI's own save logic does), or have xray_write_config() fall back to building the outbound object from the individual wizard fields when outbound_config is empty.

Originally created by @tqb333 on GitHub (Aug 1, 2026). Original GitHub issue: https://github.com/MrTheory/os-xray/issues/20 install.sh auto-import (`import_existing_config()`) populates wizard display fields but not `outbound_config`, so the imported instance fails to start **Environment:** OPNsense 26.7.1 (FreeBSD 15.1 amd64), os-xray v3.0.0, tun2socks v2.7.0, xray-core v26.3.27 **Description** When `install.sh` detects a pre-existing `xray-core`/`tun2socks` config on disk (`detect_existing()`) and imports it (`import_existing_config()`), it writes individual instance fields to `config.xml`: `server_address`, `server_port`, `vless_uuid`, `flow`, `reality_sni`, `reality_pubkey`, `reality_shortid`, `reality_fingerprint`, `socks5_port`, `tun_interface`, `mtu`, `config_mode=wizard`. These display correctly in the GUI's Instance tab afterward. However, `xray-service-control.php`'s `xray_write_config()` builds the actual runtime `outbound` block **entirely** from a separate field, `outbound_config` (a serialized JSON string of the full Xray outbound object — protocol/settings/streamSettings) — a field `import_existing_config()` never writes. Presumably this field is normally populated by the GUI controller's own save/serialize logic when a user submits the Instance form, which the CLI import path bypasses entirely. **Result:** starting an auto-imported instance fails silently from the user's point of view: ``` ERROR: outbound_config is empty ERROR: config file not found after write: /usr/local/etc/xray-core/config-<uuid>.json ``` even though every field looks correctly populated in the GUI. **Steps to reproduce** 1. Manually place a valid `xray-core` `config.json` (vless+reality outbound) at `/usr/local/etc/xray-core/config.json` and a matching `tun2socks` `config.yaml` at `/usr/local/tun2socks/config.yaml` *before* running `install.sh` on a fresh install. 2. Run `install.sh` — it correctly detects and reports the existing config (`[FOUND] Existing xray/tun2socks config detected: ...`), and the GUI Instance tab shows all fields populated. 3. Try to start the instance — it fails as above. **Workaround that confirms root cause** Manually adding `<outbound_config>{"protocol":"vless","settings":{...},"streamSettings":{...}}</outbound_config>` (the same object as `config.json`'s `outbounds[0]`) directly to the instance in `config.xml` makes the instance start immediately, with no other changes. **Suggested fix** Either have `import_existing_config()` also construct and write `outbound_config` from the detected values (mirroring whatever the GUI's own save logic does), or have `xray_write_config()` fall back to building the outbound object from the individual wizard fields when `outbound_config` is empty.
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
MrTheory/os-xray#14
No description provided.