MHSanaei/3x-ui · error
missing required user field %q
Error message
missing required user field %q
What it means
getRequiredUserString in internal/xray/api.go reports a missing key (or explicit nil value) in the user map used to build Xray protocol accounts for the handler API. Every protocol branch first pulls its mandatory fields — typically 'email' plus protocol-specific ones like 'publicKey' for wireguard — so this error names exactly which field the inbound's client settings lack.
Source
Thrown at internal/xray/api.go:63
var (
trafficRegex = regexp.MustCompile(`(inbound|outbound)>>>([^>]+)>>>traffic>>>(downlink|uplink)`)
clientTrafficRegex = regexp.MustCompile(`user>>>([^>]+)>>>traffic>>>(downlink|uplink)`)
)
// XrayAPI is a gRPC client for managing Xray core configuration, inbounds, outbounds, and statistics.
type XrayAPI struct {
HandlerServiceClient *command.HandlerServiceClient
StatsServiceClient *statsService.StatsServiceClient
RoutingServiceClient *routerService.RoutingServiceClient
grpcClient *grpc.ClientConn
isConnected bool
StatsLastValues map[string]int64
}
func getRequiredUserString(user map[string]any, key string) (string, error) {
value, ok := user[key]
if !ok || value == nil {
return "", fmt.Errorf("missing required user field %q", key)
}
strValue, ok := value.(string)
if !ok {
return "", fmt.Errorf("invalid type for user field %q: %T", key, value)
}
return strValue, nil
}
func getOptionalUserString(user map[string]any, key string) (string, error) {
value, ok := user[key]
if !ok || value == nil {
return "", nil
}
strValue, ok := value.(string)
if !ok {View on GitHub (pinned to ad32144c42)
Solutions
- Inspect the error's %q field name, then open the inbound's client entry in the panel and fill in that exact field (e.g. set the client email / wireguard publicKey) and save, which regenerates the user map.
- If the field genuinely exists in the stored JSON, check for a nil value — the guard treats nil the same as missing; remove the null or set a real value.
- If the error appears right after a panel upgrade on old inbounds, migrate the stored clients (add the now-required field) rather than hand-patching Xray.
Example fix
// before — client map missing email
user := map[string]any{"id": uuidStr, "level": 0}
// after
user := map[string]any{"email": "alice@example.com", "id": uuidStr, "level": 0} Defensive patterns
Strategy: validation
Validate before calling
// Validate required fields before building the Xray user
required := []string{"email"}
if proto == "wireguard" {
required = append(required, "publicKey")
}
for _, k := range required {
if v, ok := user[k]; !ok || v == nil {
return fmt.Errorf("client settings missing %q", k)
}
} Type guard
func hasRequiredUserFields(user map[string]any, keys ...string) bool {
for _, k := range keys {
v, ok := user[k]
if !ok || v == nil {
return false
}
if _, isStr := v.(string); !isStr {
return false
}
}
return true
} Try / catch
if err != nil {
if strings.Contains(err.Error(), "missing required user field") {
// extract field name from message, fix client entry in panel, no retry
}
} Prevention
- Create clients through the panel UI/API so mandatory fields are enforced at insert.
- Validate imported client JSON against the Zod schemas before writing it to the inbound.
When it happens
Trigger: Calling the user-add path (AddUser/AlterInbound construction in api.go) with a client map lacking 'email', a wireguard client without 'publicKey', etc. Concretely: malformed client JSON in the inbound settings, an API/manual insertion that skipped a mandatory field, or a protocol handler expecting a field the stored client model never wrote.
Common situations: Hand-edited inbound settings JSON missing a field; a client created through a path that only sets flow/id but not email; wireguard clients created before a version that started requiring publicKey; schema drift between the panel's stored client objects and a newer Xray-core expectation.
Related errors
- local xray is not running
- username can not be empty
- password can not be empty
- xray is not running
- invalid metric (unknown metric)
AI-assisted analysis of MHSanaei/3x-ui@ad32144c42 (2026-08-15).
Data as JSON: /api/errors/832458ef9399698c.
Report an issue: GitHub.