{"record":{"id":"b32929e614299a1d","repo":"XTLS/Xray-core","slug":"unknown-config-id","errorCode":null,"errorMessage":"unknown config id: ","messagePattern":"unknown config id: ","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"infra/conf/loader.go","lineNumber":26,"sourceCode":")\n\ntype ConfigCreator func() interface{}\n\ntype ConfigCreatorCache map[string]ConfigCreator\n\nfunc (v ConfigCreatorCache) RegisterCreator(id string, creator ConfigCreator) error {\n\tif _, found := v[id]; found {\n\t\treturn errors.New(id, \" already registered.\").AtError()\n\t}\n\n\tv[id] = creator\n\treturn nil\n}\n\nfunc (v ConfigCreatorCache) CreateConfig(id string) (interface{}, error) {\n\tcreator, found := v[id]\n\tif !found {\n\t\treturn nil, errors.New(\"unknown config id: \", id)\n\t}\n\treturn creator(), nil\n}\n\ntype JSONConfigLoader struct {\n\tcache     ConfigCreatorCache\n\tidKey     string\n\tconfigKey string\n}\n\nfunc NewJSONConfigLoader(cache ConfigCreatorCache, idKey string, configKey string) *JSONConfigLoader {\n\treturn &JSONConfigLoader{\n\t\tidKey:     idKey,\n\t\tconfigKey: configKey,\n\t\tcache:     cache,\n\t}\n}\n","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/infra/conf/loader.go#L8-L44","documentation":"Returned by ConfigCreatorCache.CreateConfig when asked to instantiate a config whose inbound/outbound protocol id is not in the creator registry. Protocol creators register themselves by name (vless, vmess, trojan, etc.); an unregistered id means either a typo'd protocol name or a protocol whose package was not compiled/registered into this binary. Note this is distinct from the 'already registered' duplicate-registration error in the same cache.","triggerScenarios":"Setting an inbound or outbound protocol string to an unsupported or misspelled value, e.g. \"vmes\", \"socks5\" (should be socks), \"shadowsocks \" with trailing space, or a protocol that exists only in a fork build. Also triggered programmatically by calling CreateConfig with an id never registered via RegisterCreator.","commonSituations":"Copy-pasting configs between Xray forks (e.g. sing-box protocol names like 'hysteria2' where Xray expects 'hysteria'); using a minimal build without certain protocols compiled in; whitespace/case mistakes in the protocol field.","solutions":["Correct the protocol name to one supported by this Xray build (vless, vmess, trojan, shadowsocks, socks, http, freedom, blackhole, wireguard, hysteria, ...)","Verify case and trim whitespace in the protocol field","If the protocol genuinely exists in Xray but fails, your binary may lack that module — use a full official build"],"exampleFix":"// before\n{ \"protocol\": \"socks5\", \"settings\": {} }\n// after\n{ \"protocol\": \"socks\", \"settings\": {} }","handlingStrategy":"type-guard","validationCode":"// Validate protocol against the supported set before creating config\nvar supportedProtocols = map[string]bool{\n\t\"vless\": true, \"vmess\": true, \"trojan\": true, \"shadowsocks\": true,\n\t\"socks\": true, \"http\": true, \"freedom\": true, \"blackhole\": true,\n\t\"wireguard\": true, \"hysteria\": true, \"loopback\": true,\n}\nif !supportedProtocols[strings.ToLower(protocolName)] {\n\treturn fmt.Errorf(\"unsupported protocol %q\", protocolName)\n}","typeGuard":"func isSupportedProtocol(p string) bool {\n\t_, ok := supportedProtocols[strings.ToLower(strings.TrimSpace(p))]\n\treturn ok\n}","tryCatchPattern":null,"preventionTips":["Trim and lowercase protocol names before validation","Do not mix protocol vocabularies from other cores (socks5 vs socks, hysteria2 vs hysteria)"],"tags":["xray","config","loader","protocol","registry"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}