XTLS/Xray-core · error
unknown type
Error message
unknown type
What it means
PraseByteSlice (infra/conf/transport_finalmask.go:63) decodes a raw JSON "packet" value according to the item's "type" field. Only ""/"array" (JSON byte array), "str", "hex", and "base64" are recognized; any other type string returns "unknown type" and the transport config fails to build.
Source
Thrown at infra/conf/transport_finalmask.go:63
var str string
if err := json.Unmarshal(data, &str); err != nil {
return nil, err
}
return []byte(str), nil
case "hex":
var str string
if err := json.Unmarshal(data, &str); err != nil {
return nil, err
}
return hex.DecodeString(str)
case "base64":
var str string
if err := json.Unmarshal(data, &str); err != nil {
return nil, err
}
return base64.StdEncoding.DecodeString(str)
default:
return nil, errors.New("unknown type")
}
}
var (
customVarNamePattern = regexp.MustCompile(`^[A-Za-z_][A-Za-z0-9_]*$`)
tcpmaskLoader = NewJSONConfigLoader(ConfigCreatorCache{
"header-custom": func() interface{} { return new(HeaderCustomTCP) },
"fragment": func() interface{} { return new(FragmentMask) },
"sudoku": func() interface{} { return new(Sudoku) },
"xmc": func() interface{} { return new(XMC) },
}, "type", "settings")
udpmaskLoader = NewJSONConfigLoader(ConfigCreatorCache{
"header-custom": func() interface{} { return new(HeaderCustomUDP) },
"mkcp-legacy": func() interface{} { return new(MkcpLegacy) },
"noise": func() interface{} { return new(NoiseMask) },
"salamander": func() interface{} { return new(Salamander) },View on GitHub (pinned to 7d214f8b09)
Solutions
- Set type to one of "array" (or omit), "str", "hex", "base64"
- Match payload to type: str/hex/base64 take a JSON string; array takes [1,2,3]
- Omit type entirely and supply the packet as a JSON byte array
Example fix
// before
{ "type": "ascii", "packet": "GET / HTTP/1.1\r\n" }
// after
{ "type": "str", "packet": "GET / HTTP/1.1\r\n" } Defensive patterns
Strategy: validation
Validate before calling
const okTypes = new Set(['', 'array', 'str', 'hex', 'base64']);
for (const item of [...(mask.client??[]), ...(mask.server??[]), ...(mask.noise??[])]) {
if (item.packet && item.type && !okTypes.has(item.type.toLowerCase())) throw new Error(`unknown packet type: ${item.type}`);
if (['str','hex','base64'].includes((item.type??'').toLowerCase()) && typeof item.packet !== 'string') throw new Error('str/hex/base64 packets must be JSON strings');
if ((item.type??'') === '' || item.type === 'array') { if (!Array.isArray(item.packet)) throw new Error('array packets must be JSON byte arrays'); }
} Type guard
const isPacketType = (t: string) => ['','array','str','hex','base64'].includes(t.toLowerCase());
Prevention
- Standardize on one encoding (hex or str) across all masks
- Add a unit test that validates mask JSON against the allow-list before deploy
When it happens
Trigger: A TCPItem/UDPItem/NoiseItem with "type":"utf8" (or "b64", "Hex", any misspelling) and a non-empty packet. Note strings.ToLower is applied, so "Hex" works but "hexadecimal" does not. Empty type with a JSON array [104,105] is the default and valid.
Common situations: Hand-writing header-custom/noise masks and guessing the type vocabulary; copying examples from third-party clients that use different type names; typos like "base64 " with trailing whitespace.
Related errors
- invalid fakedns config
- failed to parse Socks user
- failed to parse socks account
- gecko: invalid min/max packet size
- invalid scheme + u.Scheme
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/8fb50d00c1970bc9.
Report an issue: GitHub.