{"record":{"id":"b4a8dccd24d32eb5","repo":"XTLS/Xray-core","slug":"invalid-vmess-user","errorCode":null,"errorMessage":"invalid VMess user","messagePattern":"invalid VMess user","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/vmess.go","lineNumber":81,"sourceCode":"// Build implements Buildable\nfunc (c *VMessInboundConfig) Build() (proto.Message, error) {\n\terrors.PrintNonRemovalDeprecatedFeatureWarning(\"VMess (with no Forward Secrecy, etc.)\", \"VLESS Encryption\")\n\n\tconfig := &inbound.Config{}\n\n\tif c.Defaults != nil {\n\t\tconfig.Default = c.Defaults.Build()\n\t}\n\n\tif c.Clients != nil {\n\t\tc.Users = c.Clients\n\t}\n\tconfig.User = make([]*protocol.User, len(c.Users))\n\tprocessUser := func(idx int) error {\n\t\trawData := c.Users[idx]\n\t\tuser := new(protocol.User)\n\t\tif err := json.Unmarshal(rawData, user); err != nil {\n\t\t\treturn errors.New(\"invalid VMess user\").Base(err)\n\t\t}\n\t\taccount := new(VMessAccount)\n\t\tif err := json.Unmarshal(rawData, account); err != nil {\n\t\t\treturn errors.New(\"invalid VMess user\").Base(err)\n\t\t}\n\n\t\tu, err := uuid.ParseString(account.ID)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\taccount.ID = u.String()\n\n\t\tuser.Account = serial.ToTypedMessage(account.Build())\n\t\tconfig.User[idx] = user\n\t\treturn nil\n\t}\n\tif err := task.ParallelForN(len(c.Users), processUser); err != nil {\n\t\treturn nil, err","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/vmess.go#L63-L99","documentation":"Thrown by VMessInboundConfig.Build() (processUser closure) when a raw entry of the inbound \"clients\"/\"users\" array fails to unmarshal into protocol.User. The first decode pass expects the common user envelope: \"email\" as string and \"level\" as a JSON number. A type mismatch or malformed JSON fragment makes json.Unmarshal fail and this error wraps the cause.","triggerScenarios":"\"clients\":[{\"email\":\"a@b\",\"level\":\"1\"}] — level quoted; broken JSON in one client object; a nested object where a scalar is expected. Note c.Clients is aliased into c.Users before processing, so both keys are validated identically.","commonSituations":"YAML frontends or templates quoting all values; hand-editing client lists; importing client arrays from panels that emit stringly-typed levels.","solutions":["Read the .Base(err) json cause — it names the exact field and expected type","Ensure level is an unquoted number and email a string","Run the config through a JSON validator (jq, jsonlint) before starting Xray"],"exampleFix":"// before\n\"clients\": [ { \"id\": \"...\", \"level\": \"0\", \"email\": \"u\" } ]\n// after\n\"clients\": [ { \"id\": \"...\", \"level\": 0, \"email\": \"u\" } ]","handlingStrategy":"validation","validationCode":"func validateVMessClients(cfg map[string]any) error {\n\tinbounds, _ := cfg[\"inbounds\"].([]any)\n\tfor _, ib := range inbounds {\n\t\tm, _ := ib.(map[string]any)\n\t\tif p, _ := m[\"protocol\"].(string); p != \"vmess\" { continue }\n\t\tsettings, _ := m[\"settings\"].(map[string]any)\n\t\tclients, _ := settings[\"clients\"].([]any)\n\t\tfor i, c := range clients {\n\t\t\tcm, _ := c.(map[string]any)\n\t\t\tif l, ok := cm[\"level\"]; ok {\n\t\t\t\tif _, isNum := l.(float64); !isNum {\n\t\t\t\t\treturn fmt.Errorf(\"inbound %v: clients[%d].level must be a number\", m[\"tag\"], i)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif e, ok := cm[\"email\"]; ok {\n\t\t\t\tif _, isStr := e.(string); !isStr {\n\t\t\t\t\treturn fmt.Errorf(\"inbound %v: clients[%d].email must be a string\", m[\"tag\"], i)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":"func vmessClientEnvelopeOK(raw json.RawMessage) bool {\n\tvar user protocol.User\n\treturn json.Unmarshal(raw, &user) == nil\n}","tryCatchPattern":null,"preventionTips":["level is a number, email is a string — enforce types in generators and templates","Validate client entries with json.Unmarshal into protocol.User before deploy","Prefer JSON (not YAML) sources, or type-aware YAML conversion, to avoid accidental quoting"],"tags":["vmess","inbound","clients","json","unmarshal","config","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}