Core Configuration
XRay configuration validation, default values, and API documentation
XRay Configuration Documentation
This document explains how PasarGuard validates and processes XRay configuration files. It's designed to help beginners understand the validation process, default values, and API limitations.
Table of Contents
- Overview
- Configuration Validation
- Default Values
- Supported Protocols
- Network Types
- Security Settings
- Viewing Connected IPs
- API Limits and Constraints
- Common Validation Errors
Overview
The XRayConfig class is responsible for:
- Validating XRay configuration JSON files
- Extracting default values from configuration
- Processing inbound and outbound settings
- Handling special configurations like fallbacks and TLS/Reality
When you create or modify a core configuration through the API, PasarGuard automatically validates your XRay config using this class.
Configuration Validation
Required Fields
Your XRay configuration must include:
-
inbounds- Array of inbound configurations- Cannot be empty or missing
- Each inbound must have a unique
tag - Each inbound must have a
protocolfield
-
outbounds- Array of outbound configurations- Cannot be empty or missing
- Each outbound must have a unique
tag
Inbound Tag Rules
Inbound tags have strict rules:
- ✅ Must be unique - No two inbounds can have the same tag
- ✅ Must be present - Every inbound requires a tag
- ❌ Cannot contain comma (
,) - The character,is not allowed - ❌ Cannot contain
<=>- This sequence is reserved for fallback handling
Port Requirements
Most inbounds must have a port field. The only exception is when:
- The inbound is used as a fallback destination (referenced by another inbound's fallback settings)
- The inbound has its own
fallbacksarray in settings
Port Requirement
Most inbounds require a port field. Only fallback inbounds (those referenced by other inbounds or with their own fallbacks array) can omit the port.
Example:
{
"tag": "main-inbound",
"port": 443, // ✅ Required for most inbounds
"protocol": "vless"
}Default Values
When processing your configuration, PasarGuard extracts and sets default values for various settings. Here's what gets set automatically:
Base Settings (All Inbounds)
These defaults are applied to every inbound:
| Field | Default Value | Description |
|---|---|---|
network | "tcp" | Transport network type |
tls | "none" | Security/encryption type |
sni | [] | Server Name Indication list (empty array) |
host | [] | Host header list (empty array) |
path | "" | Path string (empty) |
header_type | "" | Header type (empty string) |
is_fallback | false | Whether this is a fallback inbound |
fallbacks | [] | Fallback configurations (empty array) |
port | None | Port number (must be provided in config) |
Protocol-Specific Defaults
VLESS Protocol Defaults:
flow:""(empty string) - Flow control settingencryption:"none"- Encryption methoddecryption:"none"- Decryption method
If decryption is not "none", then encryption must also be provided.
Shadowsocks Protocol Defaults:
method:""- Encryption method (must be specified)is_2022:false- Whether using 2022-blake3 methodspassword: Must be valid base64 string (for 2022-blake3 methods)
Shadowsocks Restrictions
- ❌
2022-blake3-chacha20-poly1305method is not supported - ✅ Only
2022-blake3-aes-*-gcmmethods are supported
Reality Security Defaults:
| Field | Default Value | Description |
|---|---|---|
fp | "chrome" | Fingerprint type |
tls | "reality" | Security type |
sni | From serverNames in realitySettings | Server names |
pbk | Calculated from privateKey | Public key (auto-generated) |
sids | From shortIds in realitySettings | Short IDs (required) |
spx | "" | SpiderX setting (optional) |
mldsa65Verify | From realitySettings | MLDSA65 verification |
Required Reality Settings:
- ✅
privateKey- Must be provided - ✅
shortIds- At least one short ID must be defined - ✅
serverNames- Used for SNI
Supported Protocols
PasarGuard processes and validates these protocols:
- Vmess
- Vless
- Trojan
- Shadowsocks
Other protocols in your config (like socks, http) will be ignored during processing but won't cause errors.
Network Types
The following network/transport types are supported:
| Network Type | Description | Special Handling |
|---|---|---|
tcp | TCP transport | Default network type |
raw | Raw TCP | Same handling as TCP |
ws | WebSocket | Path and host must be strings |
grpc | gRPC | Uses serviceName as path |
gun | gUN | Same as gRPC |
quic | QUIC | Uses key as path |
httpupgrade | HTTP Upgrade | Standard path/host handling |
splithttp | Split HTTP | Includes mode setting |
xhttp | XHTTP | Includes mode setting |
kcp | KCP | Uses seed as path |
http | HTTP/1.1 | Standard HTTP |
h2 | HTTP/2 | Standard HTTP |
h3 | HTTP/3 | Standard HTTP |
Network-Specific Rules
TCP/Raw Networks:
pathandhostin headers must be arrays (not strings)- If
pathis an array, only the first element is used hostcan be an array of host values
Example:
{
"streamSettings": {
"network": "tcp",
"tcpSettings": {
"header": {
"type": "http",
"request": {
"path": ["/path"], // ✅ Array
"headers": {
"Host": ["example.com"] // ✅ Array
}
}
}
}
}
}WebSocket (WS):
pathandhostmust be strings (not arrays)hostis converted to a single-element array internally
Example:
{
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "/path", // ✅ String
"host": "example.com" // ✅ String
}
}
}gRPC:
pathis extracted fromserviceNamehostis extracted fromauthority
Example:
{
"streamSettings": {
"network": "grpc",
"grpcSettings": {
"serviceName": "my-service", // Used as path
"authority": "example.com" // Used as host
}
}
}Security Settings
None (No Security)
- Default security type
- No encryption or TLS
- Used for plain connections or when encryption is handled at application level
TLS Security
When using TLS security:
Certificate Handling:
- Certificates can be provided via:
certificateFile- Path to certificate file (requireskeyFile)certificate- Direct certificate content (string or array)
- If using
certificateFile, you must also providekeyFile - SNI (Server Name Indication) is automatically extracted from certificates
Certificate Requirements
If using certificateFile, you must also provide keyFile. Both files are required.
Example:
{
"streamSettings": {
"security": "tls",
"tlsSettings": {
"certificates": [{
"certificateFile": "/path/to/cert.pem",
"keyFile": "/path/to/key.pem"
}]
}
}
}Reality Security
When using Reality security:
Required Fields:
privateKey- Private key for X25519shortIds- Array with at least one short ID (can be empty string"")serverNames- Array of server names for SNI
Optional Fields:
SpiderX- SpiderX configurationmldsa65Verify- MLDSA65 verification setting
Required Reality Settings
- ✅
privateKey- Must be provided - ✅
shortIds- At least one short ID must be defined (can be empty string) - ✅
serverNames- Used for SNI
Example:
{
"streamSettings": {
"security": "reality",
"realitySettings": {
"serverNames": ["example.com"],
"privateKey": "your-private-key-here",
"shortIds": [""]
}
}
}Viewing Connected IPs
You can enable tracking of user online statistics to see the latest IP addresses connected to your core. This feature allows you to monitor which IPs are currently connected to your XRay core.
Enabling User Online Statistics
To enable this feature, you need to add a policy section to the root of your XRay configuration JSON file. Add the following configuration:
{
"policy": {
"levels": {
"0": {
"statsUserOnline": true
}
}
},
"inbounds": [
// ... your inbound configurations
],
"outbounds": [
// ... your outbound configurations
]
}Policy Configuration
The policy section should be added at the root level of your JSON configuration file, alongside inbounds and outbounds. The statsUserOnline: true setting enables tracking of user connection statistics.
Viewing Connected IPs
After enabling the statsUserOnline policy and restarting your node:
- First Connection Required: The IP tracking will start working after the first user connection is established
- Access Statistics: Once enabled and after the first connection, you can view the latest connected IPs through your panel's statistics interface
Restart Required
After adding the policy configuration, you must restart your core for the changes to take effect.
Complete Example
Here's a complete example configuration with the policy section enabled:
{
"policy": {
"levels": {
"0": {
"statsUserOnline": true
}
}
},
"inbounds": [
{
"tag": "vless-ws-443",
"port": 443,
"protocol": "vless",
"settings": {
"clients": []
},
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "/path"
}
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom"
}
]
}API Limits and Constraints
When creating or modifying core configurations through the API, these limits apply:
Field Limits
| Field | Limit | Description |
|---|---|---|
name | Max 256 characters | Core configuration name |
exclude_inbound_tags | Combined string length max 2048 chars | Tags to exclude from processing |
fallbacks_inbound_tags | Combined string length max 2048 chars | Tags used for fallback handling |
config | Cannot be empty | Must contain valid XRay configuration |
Special Rules
-
Default Core Protection
- Core configuration with
id = 1cannot be deleted - This is the default/core system configuration
- Core configuration with
-
Tag String Length
- When
exclude_inbound_tagsandfallbacks_inbound_tagsare combined into a comma-separated string, the total length must not exceed 2048 characters - Example: If you have 100 tags of 20 characters each, that's 2000 characters (plus 99 commas = 2099) which would exceed the limit
- When
-
Config Validation
- The
configdictionary cannot be empty{} - Must pass all XRay validation rules (inbounds, outbounds, tags, etc.)
- The
Default Core Protection
Core configuration with id = 1 cannot be deleted. This is the default/core system configuration.
API Endpoints
The following endpoints are available for core configuration management:
POST /api/core- Create new core configurationGET /api/core/{core_id}- Get core configuration by IDPUT /api/core/{core_id}- Modify existing core configurationDELETE /api/core/{core_id}- Delete core configuration (except id=1)GET /api/cores- List all core configurationsPOST /api/core/{core_id}/restart- Restart nodes using this core
Authentication
All endpoints require sudo admin privileges.
Common Validation Errors
Here are common errors you might encounter and how to fix them:
Error: "config doesn't have inbounds"
Problem: Your configuration is missing the inbounds array.
Solution:
{
"inbounds": [
{
"tag": "my-inbound",
"port": 443,
"protocol": "vless"
}
],
"outbounds": []
}Error: "character «,» is not allowed in inbound tag"
Problem: Your inbound tag contains a comma or <=>.
Solution: Remove commas and <=> from tags:
{
"inbounds": [
{
"tag": "inbound,fallback", // ❌ Invalid
"port": 443,
"protocol": "vless"
},
{
"tag": "inbound-fallback", // ✅ Valid
"port": 443,
"protocol": "vless"
}
]
}Error: "{tag} inbound doesn't have port"
Problem: An inbound is missing the required port field.
Solution: Add a port number:
{
"tag": "my-inbound",
"port": 443, // ✅ Add this
"protocol": "vless"
}Error: "only 2022-blake3-aes-*-gcm methods are supported"
Problem: You're using an unsupported Shadowsocks method.
Solution: Use a supported method:
{
"protocol": "shadowsocks",
"settings": {
"method": "2022-blake3-aes-128-gcm" // ✅ Supported
// "method": "2022-blake3-chacha20-poly1305" // ❌ Not supported
}
}Error: "Shadowsocks password must be a valid base64 string"
Problem: For 2022-blake3 methods, password must be base64 encoded.
Solution: Ensure password is valid base64:
{
"settings": {
"method": "2022-blake3-aes-128-gcm",
"password": "base64-encoded-password-here" // ✅ Must be base64
}
}Error: "You need to provide privateKey in realitySettings"
Problem: Reality configuration is missing the private key.
Solution:
{
"streamSettings": {
"security": "reality",
"realitySettings": {
"privateKey": "your-private-key-here", // ✅ Required
"shortIds": [""],
"serverNames": ["example.com"]
}
}
}Error: "You need to define at least one shortID in realitySettings"
Problem: Reality settings have empty or missing shortIds array.
Solution:
{
"realitySettings": {
"shortIds": [""], // ✅ At least one element (can be empty string)
// "shortIds": [] // ❌ Empty array not allowed
}
}Error: "Settings of {tag} for path and host must be list, not str"
Problem: For TCP/raw networks, path and host in headers must be arrays.
Solution:
{
"streamSettings": {
"network": "tcp",
"tcpSettings": {
"header": {
"type": "http",
"request": {
"path": ["/path"], // ✅ Array, not string
"headers": {
"Host": ["example.com"] // ✅ Array, not string
}
}
}
}
}
}Error: "Settings for path and host must be str, not list"
Problem: For WebSocket, path and host must be strings.
Solution:
{
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "/path", // ✅ String, not array
"host": "example.com" // ✅ String, not array
}
}
}Summary
Best Practices
- ✅ Always include
inboundsandoutboundsarrays - ✅ Ensure all inbounds and outbounds have unique tags
- ✅ Avoid commas and
<=>in inbound tags - ✅ Provide port numbers for inbounds (unless using fallbacks)
- ✅ Use supported protocols: vmess, vless, trojan, shadowsocks
- ✅ Follow network-specific rules for path/host formats
- ✅ Provide required fields for TLS and Reality security
- ✅ Keep tag strings under 2048 characters total
- ✅ The default core (id=1) can't be deleted
For more information about XRay configuration format, refer to the official XRay documentation.