Xboard and V2board (UniProxy)
With panel_type = "newv2board", a katana node takes its description and its users from a panel that implements the UniProxy node API under /api/v1/server/UniProxy/. Xboard and V2board are the panels this API comes from, and the ones this page describes. katana polls the panel, builds the listener the panel describes, and sends back per-user traffic.
Read this page when you connect katana to one of these panels, when you move a node over from another node agent, or when a node does not come up and you need to know what katana asked the panel. The general layout of the config file is on Config file; this page covers what is specific to UniProxy.
At a glance
Section titled “At a glance”| Property | UniProxy in katana |
|---|---|
panel_type |
"newv2board", or its alias "v2board", matched without regard to case |
| Authentication | [node.api].key, sent as the token query parameter on every request |
| Node types | VMess, VLESS, Trojan, Shadowsocks, Hysteria 2 |
| Node description | GET …/UniProxy/config, with ETag caching |
| Users | GET …/UniProxy/user, with ETag caching |
| Traffic | POST …/UniProxy/push, one row per user with traffic |
| Audit | Panel routes whose action is block, plus an optional local rule file. Hits are not reported. |
| Poll interval | [node.controller].update_periodic, default 60 seconds. The panel’s own intervals are ignored. |
| Not implemented | Online users and IPs (alive, alivelist), node status (status), the /api/v2/server/ routes |
Set up the node in the panel
Section titled “Set up the node in the panel”The panel owns the node’s shape: the protocol, the port, the transport and whether TLS is on. katana owns everything local to the machine: which address to bind, the certificate, routing and outbounds.
-
Create the node. Pick the protocol (VMess, VLESS, Trojan, Shadowsocks or Hysteria), then set the port, the transport and TLS the way clients should connect. How panel settings map to what katana serves lists the choices katana can serve. Leave the panel’s certificate settings alone; katana does not read them.
-
Give the node users. Attach the node to the user groups (or plans) whose users should reach it. Xboard answers with an empty user list for a node that belongs to no group, and katana binds nothing while the list is empty.
-
Note the node ID. It is the number the panel shows for the node. Xboard looks the node up by this ID and by the node type katana sends, so a
node_typethat does not match the node’s protocol getsServer does not existeven when the ID is right. -
Note the server communication key. This is the panel-wide secret node agents authenticate with, in the panel’s node or server settings. katana calls it
key. -
Get a certificate for the name clients connect to, if the node uses TLS or is a Hysteria node. katana reads it from local files, never from the panel.
Minimal example
Section titled “Minimal example”This config serves one VMess node from an Xboard panel. Whatever the panel says about the port, the transport and TLS, katana follows; the certificate is used only if the panel turns TLS on.
[log]level = "info"
[[node]]panel_type = "NewV2board"
[node.api]host = "https://panel.example.com"node_id = 1key = "replace-with-the-panel-key"node_type = "vmess"timeout = 10
[node.controller]listen_ip = "0.0.0.0"update_periodic = 60
[node.controller.cert]mode = "file"cert_file = "/etc/katana/cert/fullchain.pem"key_file = "/etc/katana/cert/privkey.pem"Check it before you start katana:
katana --test -c /etc/katana/config.tomlConfiguration OK--test builds the panel client and the router, but it does not contact the panel. It cannot tell you whether the node ID, the key or the node type match what the panel has, and it cannot tell you whether the node the panel describes is one katana can serve. Hysteria 2 nodes are the exception for the local part: --test checks their [node.hysteria] block and reads their certificate.
When katana starts and the panel answers, the node logs:
INFO katana::manager::node: node 1: listening on 0.0.0.0:443One node per protocol
Section titled “One node per protocol”The only line that changes between protocols is node_type, plus enable_vless for VLESS and a [node.hysteria] block for Hysteria 2. Each tab shows the [[node]] entry on its own.
[[node]]panel_type = "NewV2board"
[node.api]host = "https://panel.example.com"node_id = 1key = "replace-with-the-panel-key"node_type = "vmess"
# Needed only if the panel turns TLS on for this node.[node.controller.cert]mode = "file"cert_file = "/etc/katana/cert/fullchain.pem"key_file = "/etc/katana/cert/privkey.pem"[[node]]panel_type = "NewV2board"
[node.api]host = "https://panel.example.com"node_id = 2key = "replace-with-the-panel-key"node_type = "vless"enable_vless = true # without this, katana serves VMess
[node.controller.cert]mode = "file"cert_file = "/etc/katana/cert/fullchain.pem"key_file = "/etc/katana/cert/privkey.pem"[[node]]panel_type = "NewV2board"
[node.api]host = "https://panel.example.com"node_id = 3key = "replace-with-the-panel-key"node_type = "trojan"
# Trojan always runs over TLS.[node.controller.cert]mode = "file"cert_file = "/etc/katana/cert/fullchain.pem"key_file = "/etc/katana/cert/privkey.pem"[[node]]panel_type = "NewV2board"
[node.api]host = "https://panel.example.com"node_id = 4key = "replace-with-the-panel-key"node_type = "shadowsocks"
# No certificate: Shadowsocks has no TLS layer.[[node]]panel_type = "NewV2board"
[node.api]host = "https://panel.example.com"node_id = 5key = "replace-with-the-panel-key"node_type = "hysteria2" # not "hy2": see below
# Every Hysteria 2 node needs a certificate: its TLS is part of QUIC.[node.controller.cert]mode = "file"cert_file = "/etc/katana/cert/fullchain.pem"key_file = "/etc/katana/cert/privkey.pem"
# port = 0 (the default) means the panel supplies the port and obfuscation.[node.hysteria]udp = trueThe Hysteria 2 listener settings that no panel describes, such as UDP relay, the credential format and the masquerade page, are covered on Hysteria 2 nodes.
Settings
Section titled “Settings”These are the [[node]] keys that matter for a UniProxy panel. panel_type sits directly in [[node]]; the others live in [node.api] unless the key names another table. The complete list of node keys is on Config file.
| Key | Type | Default | With a UniProxy panel |
|---|---|---|---|
panel_type |
string | "" |
"newv2board" or "v2board", in any case. Anything else fails with unknown panel_type "…". |
host |
string | "" |
Panel base URL, including the scheme. katana removes any trailing / and appends /api/v1/server/UniProxy/…, so a base path such as https://example.com/panel is kept. Not checked by --test. |
node_id |
u32 | 0 |
The node’s numeric ID, sent as the node_id query parameter. |
key |
string | "" |
The server communication key, sent as the token query parameter. |
node_type |
string (enum) | "" |
Which protocol to serve and which node type to ask the panel for. Accepted values, in any case: v2ray, vmess, vless, trojan, shadowsocks, hysteria2, hysteria, hy2. Anything else fails with unknown node_type "…". See node_type. |
enable_vless |
bool | false |
For a V2ray-family node: serve VLESS instead of VMess, ask the panel for node_type=vless, and read the transport settings from network_settings. Ignored for other node types. |
timeout |
u64 | 0 |
Total time for one panel request, in seconds. 0 means 5 seconds. |
speed_limit |
float | 0.0 |
Mbps. A value above 0 replaces every user’s panel limit with this one. See Speed limits. |
rule_list_path |
string | "" |
A local file of audit regexes, added to the rules from the panel. See Audit rules. |
vless_flow |
string | "" |
No effect with this panel. The flow comes from the panel’s flow field. |
device_limit |
integer | 0 |
No effect. katana does not enforce device limits. |
disable_custom_config |
bool | false |
No effect. SSPanel only. |
[node.controller] update_periodic |
u64 | 60 |
Seconds between polls. One timer drives the node fetch, the user fetch, the rule refresh and the traffic report. Values below 1 count as 1. |
[node.controller] disable_get_rule |
bool | false |
true stops katana from loading audit rules, both the panel’s and the local file’s. Rules already loaded before a reload turns this on stay in force until katana restarts or a reload replaces the node. |
[node.controller] disable_upload_traffic |
bool | false |
true stops traffic reports. The counts of users who leave the node are discarded. The counters of current users keep running, so turning reports back on with a reload also reports what they moved in the meantime. |
[node.hysteria] port |
u16 | 0 |
Hysteria 2 only. 0 asks the panel for the node. A non-zero port describes the node locally, and katana never calls the config endpoint. |
node_type
Section titled “node_type”node_type does two jobs. It picks the protocol katana serves, and, lowercased, it becomes the node_type query parameter the panel uses to find the node. The one exception is a V2ray-family node with enable_vless = true: katana then sends vless, whatever you wrote.
node_type (any case) |
enable_vless |
katana serves | Sent to the panel | Xboard |
|---|---|---|---|---|
v2ray |
false |
VMess | v2ray |
Accepted, as an alias of vmess |
vmess |
false |
VMess | vmess |
Accepted |
v2ray, vmess or vless |
true |
VLESS | vless |
Accepted |
vless |
false |
VMess | vless |
Accepted, but the protocols do not match |
trojan |
ignored | Trojan | trojan |
Accepted |
shadowsocks |
ignored | Shadowsocks | shadowsocks |
Accepted |
hysteria2 |
ignored | Hysteria 2 | hysteria2 |
Accepted, as an alias of hysteria |
hysteria |
ignored | Hysteria 2 | hysteria |
Accepted |
hy2 |
ignored | Hysteria 2 | hy2 |
Refused: Invalid node type specified |
What katana asks the panel
Section titled “What katana asks the panel”katana calls three endpoints, all under host. Every request, including the POST, carries the same three query parameters:
| Parameter | Value |
|---|---|
node_id |
[node.api].node_id |
node_type |
The lowercased node_type, or vless (see node_type) |
token |
[node.api].key |
| Call | When | Response katana reads |
|---|---|---|
GET /api/v1/server/UniProxy/config |
At startup and every poll. Skipped for a Hysteria 2 node with a local [node.hysteria].port. |
A JSON object describing the node, without an envelope. See Fields katana reads. |
GET /api/v1/server/UniProxy/user |
At startup and every poll | {"users": [{"id": …, "uuid": "…", "speed_limit": …}, …]} |
POST /api/v1/server/UniProxy/push |
Every poll, if any user has traffic | Only the HTTP status. The body is ignored. |
sequenceDiagram
participant K as katana node
participant P as Panel
K->>P: GET config
P-->>K: node description and routes
K->>P: GET user
P-->>K: user list
Note over K: bind the listener, load audit rules
loop every update_periodic seconds
K->>P: GET config (If-None-Match)
P-->>K: 200 with a new description, or 304
K->>P: GET user (If-None-Match)
P-->>K: 200 with a new list, or 304
Note over K: reconcile, refresh audit rules
K->>P: POST push
end
ETags and 304
Section titled “ETags and 304”katana keeps one ETag per endpoint, one for config and one for user. When a full answer carries an ETag header, katana stores it and sends it back as If-None-Match on the next request to the same endpoint. Xboard answers 304 Not Modified when nothing has changed, and katana then keeps the node description or the user list it last applied, without parsing anything. A response without an ETag header leaves the stored tag as it was.
katana stores the tag as soon as the panel answers 200, before it parses the body. If a running node gets an answer it rejects, for example a user list it cannot parse or a node without a port, the next poll still carries the new tag, Xboard answers 304, and katana keeps the last state it applied without logging the error again. katana reads the rejected answer again in three cases:
- its content changes in the panel;
- a config edit to
[node.api]gives the node a new panel client, which holds no tags and reads both endpoints in full; - katana restarts, or a reload replaces the node.
While a node is coming up, every attempt forgets the stored tags and asks the panel afresh, so an answer rejected at startup is read again at each retry.
Startup, polls and failures
Section titled “Startup, polls and failures”-
Startup. katana fetches the node description first, then the user list, then binds the listener. The first poll comes one full
update_periodicafter the node is up. -
Startup fails. Any failure on the way up is retried: the panel is unreachable or refuses the request, an answer does not parse, the panel describes a feature katana refuses, or the port is still in use. The node logs the reason at
ERRORlevel, followed by the wait before the next attempt:ERROR katana::manager::node: node 1: node_info failed: GET /api/v1/server/UniProxy/config; retrying in 1sThe wait starts at 1 second and doubles after each failure, up to 60 seconds or
update_periodic, whichever is shorter. Each attempt starts again from the node description, without ETags. Saving an edit to the node’s settings in the config file starts the next attempt at once. The node binds nothing until an attempt succeeds. -
The user list is required. A node does not come up until it has read a user list: a user fetch that fails or does not parse is a failed attempt like the others, logged as
user_list failedand retried. An empty list is accepted: the node comes up and binds nothing until users arrive. -
A later fetch fails. katana logs a warning and keeps the last applied description or user list. There is no retry within a poll; the next tick is the retry.
-
The user list is empty. katana closes the listener and binds nothing until users come back.
Failed HTTP requests are logged without their URL, because the URL carries the key. The log line names the endpoint only, for example GET /api/v1/server/UniProxy/config.
Fields katana reads
Section titled “Fields katana reads”katana reads only these fields from the config response. It does not reject unknown fields, so a panel may send anything else.
| Field | Node types | What katana does with it |
|---|---|---|
server_port |
All | The port to listen on. 0 or a missing value fails with newV2board: server port must be > 0. |
network |
VMess, VLESS | The transport: tcp or raw, ws or websocket, grpc or gun. Empty means TCP. See Transports. |
networkSettings |
VMess | path (WebSocket), headers.Host (WebSocket), serviceName (gRPC), header (TCP) |
network_settings |
VLESS | The same fields, read only when enable_vless = true |
tls |
VMess, VLESS | 0 plain, 1 TLS, 2 REALITY (refused) |
flow |
VLESS | Must be empty. Any flow is refused. |
host, server_name |
Trojan, Hysteria 2 | Recorded, and a change rebuilds the listener. They do not change what katana serves; the local certificate decides the name. |
cipher, server_key |
Shadowsocks | The cipher, and the server PSK for Shadowsocks 2022 |
obfs |
Shadowsocks | Must be empty, plain or none. Xboard does not send this field for Shadowsocks. |
obfs, obfs-password |
Hysteria 2 | Salamander obfuscation. obfs must be salamander or empty, and obfs-password must be empty when obfs is. |
routes[].match, routes[].action |
All | Audit rules. See Audit rules. |
From the user response, katana reads each user’s id (the uid traffic is reported under), uuid (the credential) and speed_limit (Mbps).
katana ignores these fields, even when the panel sends them:
| Field | Consequence |
|---|---|
base_config (push_interval, pull_interval) |
katana polls and reports every update_periodic seconds. |
tls_settings, cert_config |
The certificate always comes from [node.controller.cert]. The panel’s server name, REALITY keys and certificate mode have no effect. |
multiplex |
katana does not implement the smux, yamux or h2mux multiplexing this setting turns on in clients. Leave it off. Xray’s Mux.Cool works without any setting. |
decryption (VLESS encryption) |
VLESS clients must use encryption = "none". |
up_mbps, down_mbps (Hysteria) |
katana does not implement Brutal congestion control. Use speed limits instead. |
device_limit (users) |
Device limits are not enforced. |
plugin, plugin_opts (Shadowsocks) |
katana serves plain Shadowsocks without a plugin. |
network (Trojan) |
Trojan is always served over TCP with TLS. |
version (Hysteria) |
katana always serves Hysteria 2. |
listen_ip, protocol, custom_outbounds, custom_routes |
katana binds [node.controller].listen_ip and routes with [node.route] and [[outbound]]. |
How panel settings map to what katana serves
Section titled “How panel settings map to what katana serves”This table follows Xboard’s node form. When a row says refused, the listener build fails, the log line names the feature, and the node does not listen until the panel setting changes. When a row says ignored, katana serves anyway and clients configured for the ignored setting fail to connect.
VMess and VLESS
Section titled “VMess and VLESS”| Panel setting | katana serves |
|---|---|
| Transport TCP | TCP |
| Transport TCP with an HTTP header disguise | Plain TCP. The header setting is ignored. |
| Transport WebSocket | WebSocket at path (default /). If headers.Host is set, only requests for that host are accepted. |
| Transport gRPC | gRPC with the panel’s serviceName. With TLS, ALPN h2 is offered. |
| Transport HTTPUpgrade | Refused: node requests kernel-unsupported feature: httpupgrade transport |
| Transport XHTTP or SplitHTTP | Refused: node requests kernel-unsupported feature: splithttp transport |
| Any other transport | Refused: node requests kernel-unsupported feature: transport "…" |
| TLS on | TLS with the local certificate. Needs [node.controller.cert] mode = "file". |
| REALITY | Refused: node requests kernel-unsupported feature: REALITY |
VLESS flow such as xtls-rprx-vision |
Refused: node requests kernel-unsupported feature: VLESS XTLS flow |
| VLESS encryption | Ignored |
| Multiplex (smux, yamux, h2mux) | Ignored. Clients that use it fail; leave it off. Xray’s Mux.Cool works regardless. |
Users authenticate with their UUID. VMess runs in AEAD mode only, with alterId 0.
Trojan
Section titled “Trojan”| Panel setting | katana serves |
|---|---|
| TLS | TCP with TLS, using the local certificate |
| Transport WebSocket or gRPC | Still TCP with TLS. The transport is ignored. |
| REALITY | Ordinary TLS with the local certificate. REALITY is ignored. |
| Multiplex (smux, yamux, h2mux) | Ignored. Clients that use it fail; leave it off. |
The Trojan password is the user’s UUID.
Shadowsocks
Section titled “Shadowsocks”| Panel cipher | katana serves |
|---|---|
aes-128-gcm, aes-256-gcm, chacha20-ietf-poly1305, xchacha20-ietf-poly1305 |
Shadowsocks AEAD. Each user’s password is their UUID. |
2022-blake3-aes-128-gcm, 2022-blake3-aes-256-gcm |
Shadowsocks 2022 with one port for all users. The panel’s server_key is the server PSK, and each user’s PSK is the first 16 or 32 characters of their UUID as text, the same derivation Xboard uses for client subscriptions. |
2022-blake3-chacha20-poly1305 |
Fails: Xboard sends no server_key for this cipher, and katana reports shadowsocks-2022: PSK too short (0 < 32). Use an AES variant. |
| Any other cipher | Refused: node requests kernel-unsupported feature: shadowsocks cipher "…" |
| A plugin | Ignored |
katana serves Shadowsocks over TCP only; it does not open a UDP port for Shadowsocks.
Hysteria
Section titled “Hysteria”| Panel setting | katana serves |
|---|---|
| Version 2 | Hysteria 2 on UDP server_port, with the local certificate |
| Version 1 | Not supported. katana serves Hysteria 2 on the port, which Hysteria 1 clients cannot use, and a Version 1 obfuscation password makes the node fail with unknown obfs. |
| Obfuscation on, type Salamander | Salamander with the panel’s password. A password shorter than 4 bytes fails with obfs_password must be at least 4 bytes for salamander. |
| Obfuscation off, with a password still filled in | Fails with obfs_password is set but obfs is not; did you mean obfs = "salamander"?. Xboard sends the stored password even when obfuscation is off, so clear the password field when you turn obfuscation off. |
| Bandwidth up and down | Ignored |
| TLS server name, allow insecure | Ignored; the certificate decides the name |
Users authenticate with their UUID. With [node.hysteria] credential = "user_pass", the username is <uuid>@v2board.user and the password is the UUID. Hysteria 2 nodes covers the rest of the Hysteria settings.
Every entry in the user response becomes one account:
| Response field | katana uses it as |
|---|---|
id |
The uid that traffic is reported under |
uuid |
The credential: the VMess or VLESS ID, the Trojan password, the Shadowsocks password, or the Hysteria 2 auth string |
speed_limit |
The user’s speed limit in Mbps. 0 means no limit. |
A user who drops out of the list, for example because the panel banned them or their plan expired or ran out of traffic, loses their open connections at the next poll that sees the new list. On a VMess or VLESS node, katana leaves out any user whose uuid is not a valid UUID and logs skipping user <id>: uuid is not a valid UUID; the other users are served.
Speed limits
Section titled “Speed limits”katana converts Mbps to bytes per second by multiplying by 125 000, and enforces the result per user across all of that user’s connections on the node. The panel supplies one limit per user and no node-wide limit.
[node.api] speed_limit |
Effective limit for each user |
|---|---|
0 (default) or less |
The user’s speed_limit from the panel. 0 there means unlimited. |
Above 0 |
This value, for every user, whatever the panel says |
A change in a user’s panel limit applies at the next poll without dropping their connections: the connections they already have keep the old limit, and the ones they open after that poll get the new one. Speed limits explains how the limit is enforced.
Audit rules
Section titled “Audit rules”Xboard’s route rules double as katana’s audit rules. When the node has routes assigned in the panel, the config response carries them as routes, and katana turns every route whose action is block into one rule:
- the route’s
matchentries are joined with|into a single regular expression; - the expression is searched for, unanchored, in the destination host of each connection: the domain name the client asked for, or the IP address, without the port;
- the first rule that matches refuses the connection; a UDP packet to a matching destination is dropped.
Routes with any other action (direct, dns, proxy) are ignored. Use [node.route] for routing.
For example, a route with action block and match ["(^|\\.)example\\.org$", "^torrent\\."] refuses example.org, www.example.org and any host that starts with torrent., such as torrent.example.com.
katana needs no extra request for the rules: it rebuilds them from the last config response at every poll, together with the rules in rule_list_path. If the panel stops sending routes, the panel rules disappear at the next full config response. UniProxy has no endpoint for audit hits, so katana refuses the connection and reports nothing to the panel. Audit rules covers the local rule file and the matching in detail.
Traffic reports
Section titled “Traffic reports”At every poll, katana posts the traffic each user has moved since the last successful report:
{"1001": [52428800, 1073741824], "1002": [0, 4096]}Each key is a user’s id as a string, and each value is [upload, download] in bytes. Upload is what the user sent, download is what they received. katana counts the bytes relayed to and from the destination, so protocol and TLS overhead is not included.
- Users with no traffic are left out. When nobody has traffic, katana sends no request at all.
- katana checks only the HTTP status. On success, it subtracts exactly the reported bytes, so traffic counted while the request was in flight goes into the next report.
- On failure, katana logs
report trafficand keeps the counts; the next poll reports them together with the new traffic. If the panel did apply a report but katana never saw the answer, for example because the request timed out, those bytes are reported again. - When katana stops, and when a reload removes or replaces a node, the node reports its traffic one last time.
- With
disable_upload_traffic = true, katana posts nothing. See Settings for what happens to the counts.
Xboard takes a node’s online-user figure and its last-push time from the pushes, and keeps the figure for an hour. A node that carries no traffic sends no push, so the panel shows it as online without recent pushes. Traffic reporting describes the counters in detail.
What katana does not call
Section titled “What katana does not call”| Endpoint | What the panel is missing |
|---|---|
POST /api/v1/server/UniProxy/alive, GET …/alivelist |
Online IPs per user. The panel cannot enforce device limits with katana. |
POST /api/v1/server/UniProxy/status |
CPU, memory and disk load for the node |
/api/v2/server/… |
katana uses only the V1 routes |
ShadowsocksTidalab, TrojanTidalab |
katana uses only UniProxy |
Xboard marks a node as checked in each time katana fetches the user list, so the node shows as online as long as katana polls.
Changing settings while katana runs
Section titled “Changing settings while katana runs”katana watches its config file and applies most edits without a restart; Hot reload has the full list. For this panel:
- Changing
panel_type(other than case),host,node_idorkeyreplaces the node. So does any edit that changes the node type katana asks the panel for:node_type(other than case), orenable_vlesson av2rayorvmessnode. Xboard finds a node by its ID and its type, so each of these edits names another panel node. The old node stops, dropping its connections, and sends its final traffic report; katana then starts a fresh node, with its own traffic counters, from the panel. - Changing any other
[node.api]key, such astimeout,speed_limitorrule_list_path, applies at once. katana builds a new panel client with the new values, reads the node and its users in full, and applies the answer like a poll’s: connections are kept unless the node’s protocol or transport changes. - On a node whose requested type stays the same, for example with
node_type = "vless", changingenable_vlessrebuilds the listener, which drops that node’s connections. - An edit that leaves a node unable to build, such as an unknown
node_type, is refused as a whole. katana logsreload: node …: unknown node_type "…"; keeping current config, and every node keeps running as it was. - Changes in the panel need nothing on the katana side. katana picks them up at the next poll: a new port, transport or TLS setting rebuilds the listener and drops that node’s connections, and a changed user list is applied in place.
Common errors
Section titled “Common errors”The first two messages are what --test prints. At startup the same errors appear as node 1: unknown panel_type "xboard", and katana skips that node; if no node is left, it exits with no nodes could be started.
The node_info failed, user_list failed and initial start failed messages come from a node that is coming up. katana logs them at ERROR level with ; retrying in <N>s at the end, and the node tries again on its own, so fixing the cause is enough: the node comes up at the next attempt.
| Message | Cause | Fix |
|---|---|---|
configuration error: unknown panel_type "xboard" |
panel_type names the panel product |
Use panel_type = "newv2board" for Xboard and V2board. |
configuration error: unknown node_type "…" |
A node_type katana does not know |
Use one of the values in node_type. |
node 1: node_info failed: GET /api/v1/server/UniProxy/config |
The request failed: the panel is unreachable, or it refused the key, the node ID or the node type | Ask the panel yourself, as shown below. |
node 1: node_info failed: parse UniProxy config response |
The answer is not the JSON katana expects, for example an HTML page because host points at the wrong site |
Check host. It is the panel’s base URL, without /api/…. |
node 1: node_info failed: newV2board: server port must be > 0 |
The node has no port in the panel | Set the port in the panel. |
node 1: node_info failed: newV2board: shadowsocks obfs "…" is not supported |
The panel asks for Shadowsocks obfuscation | Turn obfuscation off in the panel. |
node 1: initial start failed: node requests kernel-unsupported feature: … |
The panel describes a feature katana refuses | Change the node in the panel; see How panel settings map to what katana serves. |
node 1: initial start failed: TLS node requires cert.mode = "file" |
The panel turned TLS on, and the node has no certificate | Add [node.controller.cert] with mode = "file", cert_file and key_file. |
node 1: initial start failed: obfs_password is set but obfs is not; … |
A Hysteria node has obfuscation off in the panel but a stored obfuscation password | Clear the password in the panel. |
node 1: user_list failed: parse UniProxy user response; retrying in … at startup, node 1: user_list: parse UniProxy user response later |
A user entry does not have the expected types, typically speed_limit set to null |
See Users. |
node 1: rebuild failed: … |
A panel change asked for something katana cannot serve | The node stays dark and retries at every poll. Fix the setting in the panel. |
node 1: report traffic: POST UniProxy push |
The traffic report failed | Nothing to do if it is temporary: the counts are kept and sent with the next report. |
When the log names only the endpoint, ask the panel directly with the values from your config. The key goes into your shell history, so clear it afterwards:
curl -sS "https://panel.example.com/api/v1/server/UniProxy/config?node_id=1&node_type=vmess&token=replace-with-the-panel-key"Xboard answers a wrong key with Invalid token, an unknown node type with Invalid node type specified, and a node ID that has no node of that type with Server does not exist. A working node answers with a JSON object that contains server_port.