MHSanaei/3x-ui · error
Failed to create test config path: %w
Error message
Failed to create test config path: %w
What it means
createTestConfigPath calls os.CreateTemp(config.GetBinFolderPath(), "xray_test_*.json") to reserve a temp config next to the xray binary. Failure means the bin folder does not exist or is not writable (CreateTemp's documented error conditions: pattern path nonexistent, permission denied, or disk full). Environmental — retrying per-item would not help.
Source
Thrown at internal/web/service/outbound/probe_http.go:288
// runHTTPProbeBatch makes one shared-process attempt for the given items,
// writing per-request outcomes into the items' results. It returns a non-nil
// error only when the process never became usable; retryPerItem reports
// whether splitting the batch into per-item instances could help (true for
// start failures / early exits that a poisoned config would explain, false
// for environmental failures like a missing binary or no free ports).
func runHTTPProbeBatch(items []*httpBatchItem, allOutbounds []any, testURL string, realDelay bool) (retryPerItem bool, err error) {
ports, release, err := reserveLoopbackPorts(len(items))
if err != nil {
return false, fmt.Errorf("Failed to reserve test ports: %w", err)
}
defer release()
cfg := buildBatchTestConfig(items, allOutbounds, ports)
configPath, err := createTestConfigPath()
if err != nil {
return false, fmt.Errorf("Failed to create test config path: %w", err)
}
defer os.Remove(configPath)
proc := newBatchProcess(cfg, configPath)
defer func() {
if proc.IsRunning() {
_ = proc.Stop()
}
}()
// Free the reserved ports just before xray binds them; the window is
// milliseconds, and a lost race makes xray exit fast, which surfaces
// below and triggers the per-item retry with fresh ports.
release()
if err := proc.Start(); err != nil {
if errors.Is(err, fs.ErrNotExist) {
// Binary missing — per-item retries would all fail the same way.
return false, fmt.Errorf("Failed to start test xray instance: %w", err)View on GitHub (pinned to ad32144c42)
Solutions
- Ensure the bin folder exists and is writable by the panel user: mkdir -p <bin folder> && chown
- Check disk space (df -h) and inode usage if the folder is fine
- Fix an incorrect XUI_BIN_FOLDER env var
Example fix
# before XUI_BIN_FOLDER=/opt/xray-bin ./x-ui # folder absent -> CreateTemp fails # after mkdir -p /opt/xray-bin && chown xui /opt/xray-bin XUI_BIN_FOLDER=/opt/xray-bin ./x-ui
Defensive patterns
Strategy: validation
Validate before calling
if info, err := os.Stat(config.GetBinFolderPath()); err != nil || !info.IsDir() {
return errors.New("bin folder missing; cannot run outbound test")
}
// optionally probe writability
if f, err := os.CreateTemp(config.GetBinFolderPath(), "pre_*.json"); err != nil {
return errors.New("bin folder not writable")
} else { f.Close(); os.Remove(f.Name()) } Try / catch
_, err := runHTTPProbeBatch(items, all, url, true)
if err != nil && strings.Contains(err.Error(), "create test config path") {
// fix folder perms/disk; do not retry until fixed
} Prevention
- Health-check the bin folder's existence and writability at panel startup
- Monitor disk space on the bin-folder volume
When it happens
Trigger: Running an outbound test when the bin folder (XUI_BIN_FOLDER override or default) is missing, read-only, owned by another user, or the disk/tmpfs is full.
Common situations: XUI_BIN_FOLDER points at a path that does not exist; panel binary run as a user without write access to /usr/local/x-ui/bin; a read-only rootfs container; full disk on a small VPS.
Related errors
- Failed to start test xray instance: %w
- Failed to reserve test ports: %w
- parse XUI_PORT: %w
- XUI_PORT must be between 1 and 65535
- sqlite backup destination already exists: %s
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/ed2b780bfa91c19e.
Report an issue: GitHub.