XTLS/Xray-core · error

android process lookup must be registered before use

Error message

android process lookup must be registered before use

What it means

common/net.FindProcess was called on Android, but no process finder was registered via RegisterAndroidProcessFinder. On Android, Xray-core cannot enumerate /proc or use sysctl the way desktop platforms do, so the lookup function must be injected by the embedding app (e.g. Xray's Android libs via JNI/Go mobile that consult ConnectionOwner).

Source

Thrown at common/net/find_process_android.go:19

//go:build android

package net

import (
	"github.com/xtls/xray-core/common/errors"
)

var androidProcessFinder func(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (int, string, string, error)

func RegisterAndroidProcessFinder(f func(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (int, string, string, error)) {
	androidProcessFinder = f
}

func FindProcess(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (int, string, string, error) {
	if androidProcessFinder != nil {
		return androidProcessFinder(network, srcIP, srcPort, destIP, destPort)
	}
	return 0, "", "", errors.New("android process lookup must be registered before use")
}

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. In the Android host app, call mux-adjacent init properly: register the finder at startup, e.g. net.RegisterAndroidProcessFinder(libcore.FindProcess) or the equivalent binding.
  2. Update the embedding library (libcore/Aars) to a version matching the Xray-core version, since the registration contract is version-locked.
  3. If process matching is not needed, disable the features that call FindProcess (e.g. routing rule with 'inboundUser'/process matching or sniffing options that need PID).
  4. For quick tests, run on linux instead where the native finder works without registration.

Example fix

// Android app startup, before starting Xray
// before: finder never registered, FindProcess always errors
// after
import "github.com/xtls/xray-core/common/net"

func init() {
    net.RegisterAndroidProcessFinder(func(network, srcIP string, srcPort uint16, destIP string, destPort uint16) (int, string, string, error) {
        return owner.FindProcessOwner(network, srcIP, srcPort, destIP, destPort) // implemented via Android ConnectionOwner API
    })
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Register at app startup, before any FindProcess use:
net.RegisterAndroidProcessFinder(myFinder) // myFinder implements the owner-lookup contract

Try / catch

// Expose a readiness check:
var androidProcessFinderRegistered atomic.Bool
func RegisterAndroidProcessFinder(f ...) { androidProcessFinder = f; androidProcessFinderRegistered.Store(true) }
// callers: if !androidProcessFinderRegistered.Load() { skip process lookup }

Prevention

When it happens

Trigger: Building for android/arm with find_process_android.go compiled in and calling FindProcess before (or without ever) calling RegisterAndroidProcessFinder.

Common situations: Running Xray-core inside a custom Android app (v2rayNG-style) that updated its libcore bindings and dropped the registration call, or a new embedding that never wired it up.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/06fe74ed9a895961. Report an issue: GitHub.