PasarGuard
Panel

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

  1. Overview
  2. Configuration Validation
  3. Default Values
  4. Supported Protocols
  5. Network Types
  6. Security Settings
  7. Viewing Connected IPs
  8. API Limits and Constraints
  9. 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:

  1. inbounds - Array of inbound configurations

    • Cannot be empty or missing
    • Each inbound must have a unique tag
    • Each inbound must have a protocol field
  2. 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
{
  "inbounds": [
    {
      "tag": "vless-ws-443",
      "port": 443,
      "protocol": "vless"
    },
    {
      "tag": "trojan-tls-8443",
      "port": 8443,
      "protocol": "trojan"
    },
    {
      "tag": "vmess-grpc",
      "port": 443,
      "protocol": "vmess"
    }
  ]
}
{
  "inbounds": [
    {
      "tag": "inbound,fallback",  // ❌ Contains comma
      "port": 443,
      "protocol": "vless"
    },
    {
      "tag": "inbound<=>fallback",  // ❌ Contains <=>
      "port": 8443,
      "protocol": "trojan"
    }
  ]
}

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 fallbacks array 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:

FieldDefault ValueDescription
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_fallbackfalseWhether this is a fallback inbound
fallbacks[]Fallback configurations (empty array)
portNonePort number (must be provided in config)

Protocol-Specific Defaults

VLESS Protocol Defaults:

  • flow: "" (empty string) - Flow control setting
  • encryption: "none" - Encryption method
  • decryption: "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 methods
  • password: Must be valid base64 string (for 2022-blake3 methods)

Shadowsocks Restrictions

  • 2022-blake3-chacha20-poly1305 method is not supported
  • ✅ Only 2022-blake3-aes-*-gcm methods are supported

Reality Security Defaults:

FieldDefault ValueDescription
fp"chrome"Fingerprint type
tls"reality"Security type
sniFrom serverNames in realitySettingsServer names
pbkCalculated from privateKeyPublic key (auto-generated)
sidsFrom shortIds in realitySettingsShort IDs (required)
spx""SpiderX setting (optional)
mldsa65VerifyFrom realitySettingsMLDSA65 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:

  1. Vmess
  2. Vless
  3. Trojan
  4. 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 TypeDescriptionSpecial Handling
tcpTCP transportDefault network type
rawRaw TCPSame handling as TCP
wsWebSocketPath and host must be strings
grpcgRPCUses serviceName as path
gungUNSame as gRPC
quicQUICUses key as path
httpupgradeHTTP UpgradeStandard path/host handling
splithttpSplit HTTPIncludes mode setting
xhttpXHTTPIncludes mode setting
kcpKCPUses seed as path
httpHTTP/1.1Standard HTTP
h2HTTP/2Standard HTTP
h3HTTP/3Standard HTTP

Network-Specific Rules

TCP/Raw Networks:

  • path and host in headers must be arrays (not strings)
  • If path is an array, only the first element is used
  • host can 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):

  • path and host must be strings (not arrays)
  • host is converted to a single-element array internally

Example:

{
  "streamSettings": {
    "network": "ws",
    "wsSettings": {
      "path": "/path",  // ✅ String
      "host": "example.com"  // ✅ String
    }
  }
}

gRPC:

  • path is extracted from serviceName
  • host is extracted from authority

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 (requires keyFile)
    • certificate - Direct certificate content (string or array)
  • If using certificateFile, you must also provide keyFile
  • 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 X25519
  • shortIds - Array with at least one short ID (can be empty string "")
  • serverNames - Array of server names for SNI

Optional Fields:

  • SpiderX - SpiderX configuration
  • mldsa65Verify - 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:

  1. First Connection Required: The IP tracking will start working after the first user connection is established
  2. 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

FieldLimitDescription
nameMax 256 charactersCore configuration name
exclude_inbound_tagsCombined string length max 2048 charsTags to exclude from processing
fallbacks_inbound_tagsCombined string length max 2048 charsTags used for fallback handling
configCannot be emptyMust contain valid XRay configuration

Special Rules

  1. Default Core Protection

    • Core configuration with id = 1 cannot be deleted
    • This is the default/core system configuration
  2. Tag String Length

    • When exclude_inbound_tags and fallbacks_inbound_tags are 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
  3. Config Validation

    • The config dictionary cannot be empty {}
    • Must pass all XRay validation rules (inbounds, outbounds, tags, etc.)

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 configuration
  • GET /api/core/{core_id} - Get core configuration by ID
  • PUT /api/core/{core_id} - Modify existing core configuration
  • DELETE /api/core/{core_id} - Delete core configuration (except id=1)
  • GET /api/cores - List all core configurations
  • POST /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: "all inbounds must have a unique tag"

Problem: Two or more inbounds have the same tag value.

Solution: Ensure each inbound has a unique tag:

{
  "inbounds": [
    {"tag": "inbound-1", "port": 443, "protocol": "vless"},
    {"tag": "inbound-2", "port": 8443, "protocol": "trojan"}  // ✅ Different tag
  ]
}

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 inbounds and outbounds arrays
  • ✅ 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.