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
- 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.
- Update the embedding library (libcore/Aars) to a version matching the Xray-core version, since the registration contract is version-locked.
- 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).
- 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
- Register the finder during app initialization, before starting the Xray instance.
- Keep the libcore binding version in lockstep with the Xray-core version.
- Disable routing features that need process lookup when registration is impossible.
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
- failed to determine if address is local:
- invalid source IP address:
- invalid destination IP address:
- metrics must have a tag or listen address
- Cannot get depended features
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/06fe74ed9a895961.
Report an issue: GitHub.