Command line
This page is the reference for the two binaries: etemenanki-app, the standalone proxy, and katana, the panel node agent. It lists every flag and its default, what the --test dry run checks and what it cannot check, the environment variables that change their behaviour, their exit codes and signal handling, and the exact text of every message the process prints outside the protocol code.
It describes the etemenanki 2.0.2 release, whose etemenanki-app still reports version 2.0.0 and is built with etemenanki-protocols 2.0.2, and katana 3.0.1, which is built with etemenanki-protocols 2.0.1. For a walk-through of running either program as a service, with systemd units and an upgrade procedure, see Running in production.
Synopsis
Section titled “Synopsis”etemenanki-app [-c <path>] [--test]etemenanki-app -h | --helpetemenanki-app -V | --version
katana [-c <path>] [--test]katana -h | --helpkatana -V | --versionBoth programs run in the foreground until they receive SIGINT or SIGTERM. Neither has subcommands, positional arguments, a daemon mode or a PID file.
Options
Section titled “Options”Both binaries accept the same four options and nothing else.
| Option | Argument | Default | What it does |
|---|---|---|---|
-c, --config |
path | config.toml |
The TOML configuration file to load. A relative path is resolved against the working directory of the process. |
--test |
none | off | Build the whole configuration, print the result and exit, without binding a socket or contacting any server. See Checking a configuration. |
-h, --help |
none | Print the help text to standard output and exit with status 0. |
|
-V, --version |
none | Print the program name and version, for example etemenanki-app 2.0.0 or katana 3.0.1, and exit with status 0. |
The path can be written in any of the forms the argument parser accepts: -c /etc/etemenanki/config.toml, -c/etc/etemenanki/config.toml, --config /etc/etemenanki/config.toml or --config=/etc/etemenanki/config.toml. The options can come in any order.
A usage mistake prints an error, the usage line and a hint to standard error, and exits with status 2. Nothing is loaded.
| Mistake | Message |
|---|---|
| Unknown option or stray argument | error: unexpected argument '--bogus' found |
-c without a path |
error: a value is required for '--config <CONFIG>' but none was supplied |
| An option given twice | error: the argument '--test' cannot be used multiple times |
The help text is short. For reference, this is what each program prints:
$ etemenanki-app --helpA minimal Xray-core-style proxy runtime
Usage: etemenanki-app [OPTIONS]
Options: -c, --config <CONFIG> Path to the TOML configuration file [default: config.toml] --test Validate the configuration and exit without binding any listener -h, --help Print help -V, --version Print version$ katana --helpXrayR-compatible proxy node agent on the Etemenanki kernel
Usage: katana [OPTIONS]
Options: -c, --config <CONFIG> Path to the TOML configuration file [default: config.toml] --test Validate the configuration and exit without binding any listener -h, --help Print help -V, --version Print versionThe config path and the working directory
Section titled “The config path and the working directory”The default, config.toml, means “a file called config.toml in the current working directory”. Under a service manager the working directory is often /, so pass -c with an absolute path.
Every relative path inside the file is also resolved against the working directory, not against the directory that holds the config file. That covers cert_file, key_file, ca_file, geoip, geosite, rule_list_path and Unix socket listen paths.
When the file cannot be opened, the error is the bare operating-system message, for example No such file or directory (os error 2), Permission denied (os error 13) or Is a directory (os error 21). It does not repeat the path, and the same message appears when a certificate, CA bundle or geodata file named inside the config is missing. Check -c first, then every path in the file.
While it runs, each program watches the directory that contains the config file, and reloads when the file changes. With a bare file name such as the default, that directory is the working directory. See etemenanki-app hot reload and katana hot reload.
Checking a configuration
Section titled “Checking a configuration”For etemenanki-app, --test runs the same build a start runs and stops just before the program would open sockets. For katana, it runs the part of a start that needs no panel, plus a check of each Hysteria 2 node’s local settings. Both read every file the build needs, so run it as the user the service runs as, from the service’s working directory: an unreadable key or a wrong relative path then fails the check instead of the start.
The check stops at the first error. Fix it and run the check again to find the next one.
flowchart LR
P["read and parse the file"] --> A{"any outbound?"}
A -- "no" --> F["error"]
A -- "yes" --> D["DNS resolver"]
D --> O["outbounds"]
O --> B["balancers"]
B --> R["routing table"]
R --> I["inbounds"]
I --> OK["Configuration OK."]In order, etemenanki-app --test:
| Step | What is checked | Files read |
|---|---|---|
| Parse | The file is UTF-8 and valid TOML, every key is known, every value has the right type. The keys inside an inbound’s or outbound’s settings table are checked later, when that inbound or outbound builds. |
The config file |
| Outbounds present | The file has at least one [[outbound]]. The first one is the default route unless [route].default names another. |
|
| DNS | [dns] names a known backend with the settings that backend needs. |
[dns].ca_file, when set |
| Outbounds | Each [[outbound]] builds: protocol, settings, keys, stream settings, TLS options. Tags are unique. |
Each outbound’s TLS ca_file, and a Hysteria 2 outbound’s ca_file |
| Balancers | Each balancer’s tag is new, every member names an outbound, every member has an upstream a health probe can reach, and the strategy is known. | |
| Routing | [route].default and every rule name an existing outbound or balancer, and every matcher is valid. |
The geoip file only when a rule uses a geoip matcher, and the geosite file only when a rule uses a geosite matcher |
| Inbounds | Each [[inbound]] builds: protocol, users, listen address, stream settings. Tags are unique. |
TLS and Hysteria 2 certificates and private keys |
--test does not check:
- that a port is free, or that the process may bind it;
- that the process may create a TUN device or install its routes;
- that upstream servers or DNS servers are reachable, or that their certificates verify;
- that the system trust store can be loaded (the TLS client and the Hysteria 2 client read it when they connect);
- that a Hysteria 2 outbound’s
ca_fileholds a usable certificate:--testreads the file, but its contents are parsed only when the outbound connects; [log].level, which is never validated (see Logging).
A normal start runs the same build and then binds the listeners, so a start fails on everything --test fails on, plus bind errors and TUN device errors.
flowchart LR
P["read and parse the file"] --> D["DNS resolver and outbound pool"]
D --> N{"any node?"}
N -- "no" --> F["error"]
N -- "yes" --> C["next node: panel client"]
C --> R["routing table"]
R --> H{"Hysteria 2 node?"}
H -- "yes" --> V["local Hysteria 2 settings and certificate"]
H -- "no" --> M{"more nodes?"}
V --> M
M -- "yes" --> C
M -- "no" --> OK["Configuration OK"]In order, katana --test:
| Step | What is checked | Files read |
|---|---|---|
| Parse | The file is UTF-8 and valid TOML, every key is known, every value has the right type. | The config file |
| DNS | [dns] names a known backend with the settings that backend needs. |
[dns].ca_file, when set, whatever the backend |
| Outbound pool | Each [[outbound]] builds. Tags are unique and none of them is a reserved name: direct, block, freedom or blackhole. |
|
| Nodes present | The file has at least one [[node]]. |
|
| Panel client, per node | panel_type is NewV2board, V2board or SSPanel (any case), and api.node_type is a known node type: V2ray, Vmess, Vless, Trojan, Shadowsocks, Hysteria2, Hysteria or Hy2 (any case). |
|
| Routing, per node | [node.route].default and every [[node.route.rule]] name an outbound in the pool (the default is direct when unset), and every matcher is valid. |
The geoip file only when a rule uses a geoip matcher, and the geosite file only when a rule uses a geosite matcher |
| Hysteria 2, per node | For a Hysteria 2 node only: [node.hysteria] and the certificate build into a working server, through the same code a start uses. [node.controller.cert].mode must be "file". |
cert_file and key_file from [node.controller.cert] |
--test does not check:
- anything that needs the panel. katana does not send a single request, so a wrong
api.host,api.keyornode_idpasses; - anything the panel supplies, such as a V2ray, Trojan or Shadowsocks node’s port, transport and TLS settings. These are checked when the node starts;
- the certificate files of nodes that are not Hysteria 2 nodes. katana reads them when the panel says the node uses TLS;
rule_list_path, which is read after the node has started and again at every poll, unlessdisable_get_ruleis set. A missing or unreadable file is logged as the warningcannot read rule_list_path <path>: <error>, not an error;- that a port is free, or that the process may bind it;
[log].level, which is never validated (see Logging).
Output of --test
Section titled “Output of --test”The two programs report the result differently. etemenanki-app writes its error through the logger, and katana writes it directly to standard error.
| etemenanki-app | katana | |
|---|---|---|
| Success | Configuration OK. on standard output, exit 0 |
Configuration OK on standard output (no full stop), exit 0 |
| Failure | configuration invalid: <error> as an ERROR log line on standard output, exit 1 |
configuration error: <error> on standard error, exit 1 |
| Parse error prefix | none | config parse error: |
| Invalid UTF-8 | invalid utf-8 sequence of 1 bytes from index 0 |
config not utf-8: invalid utf-8 sequence of 1 bytes from index 0 |
$ etemenanki-app --test -c config.tomlConfiguration OK.$ etemenanki-app --test -c config.toml2026-09-24T20:33:57.764733Z ERROR etemenanki_app: configuration invalid: TOML parse error at line 6, column 1 |6 | bogus=1 | ^^^^^unknown field `bogus`, expected one of `tag`, `protocol`, `listen`, `port`, `stream`, `address_family`, `sniffing`, `settings`Other failures you are likely to meet:
Message after configuration invalid: |
Cause |
|---|---|
No such file or directory (os error 2) |
The config file, or a file it names, does not exist at that path. |
config defines no outbounds |
The file has no [[outbound]]. An empty file fails this way. |
duplicate outbound tag: <tag> |
Two [[outbound]] sections share a tag. |
duplicate inbound tag: <tag> |
Two [[inbound]] sections share a tag. |
outbound <tag>: unknown protocol "<name>" |
protocol names no outbound protocol. |
balancer <tag> references unknown outbound tag: <member> |
A balancer member is not an outbound tag. |
Errors lists the messages of every section.
$ katana --test -c config.tomlConfiguration OK$ katana --test -c config.tomlconfiguration error: config parse error: TOML parse error at line 26, column 1 |26 | bogus = 1 | ^^^^^unknown field `bogus`, expected one of `mode`, `cert_file`, `key_file`, `reject_unknown_sni`Other failures you are likely to meet:
Message after configuration error: |
Cause |
|---|---|
No such file or directory (os error 2) |
The config file, [dns].ca_file, or a geodata file a rule needs does not exist. |
config defines no [[node]] entries |
The file has no [[node]]. An empty file fails this way. |
duplicate/reserved outbound tag <tag> |
Two [[outbound]] sections share a tag, or one uses direct, block, freedom or blackhole. |
unknown panel_type "<value>" |
panel_type is not a supported panel. The value is shown in lower case. |
unknown node_type "<value>" |
api.node_type is not a known node type. |
route references unknown outbound tag: <tag> |
A [[node.route.rule]] names an outbound that is not in the pool. |
node <id>: <error> |
A Hysteria 2 node’s local settings or certificate failed, for example node 1: obfs_password must be at least 4 bytes for salamander or node 1: No such file or directory (os error 2). |
Only the Hysteria 2 check puts the node’s node_id in front of the message. For the other per-node errors, find the node by the value the message quotes.
Errors lists the messages of every section.
Using --test in scripts
Section titled “Using --test in scripts”Check a new file before it replaces the live one. The exit status is the reliable signal: 0 means the configuration builds, anything else means it does not.
#!/bin/shset -eunew=/etc/etemenanki/config.toml.newlive=/etc/etemenanki/config.toml
if ! out=$(cd /etc/etemenanki && etemenanki-app --test -c "$new" 2>&1); then printf 'config rejected:\n%s\n' "$out" >&2 exit 1fimv "$new" "$live" # the running process notices the change and reloadsFor katana, replace the paths and the binary name. Capture both streams (2>&1) so the script sees katana’s standard-error message and etemenanki-app’s log line alike.
Exit codes
Section titled “Exit codes”| Status | etemenanki-app | katana |
|---|---|---|
0 |
--test passed; --help or --version printed; or a graceful stop after SIGINT or SIGTERM. |
Same. |
1 |
--test failed; or the start failed because the file could not be read or parsed, did not build, an inbound could not bind, or a TUN inbound could not create its device. |
--test failed; or the start failed because the file could not be read or parsed, the outbound pool did not build, the file has no [[node]], or not a single node’s panel client and routing table could be built. |
2 |
Command-line usage error. | Same. |
101 |
A panic, for example an invalid TOKIO_WORKER_THREADS. |
Same. |
128 + n in a shell |
Killed by signal n, for example 129 for SIGHUP, 137 for SIGKILL. |
Same. |
Once a process is running, only a signal ends it. Failures after that point are logged, and the process carries on:
- A reload whose file cannot be read, parsed or built keeps the old configuration, and the process keeps running. In etemenanki-app, an inbound that cannot bind during a reload is left out and the other inbounds start.
- A katana node whose panel stops answering after it has started logs a warning and tries again at the next poll.
- A katana node that fails its first start, for example because the panel could not be reached or its port could not be bound, retries until it comes up. Each failed attempt logs
node <id>: <reason>; retrying in <N>s, where<reason>isnode_info failed: …,panel returned no node info,panel returned port 0,user_list failed: …,panel returned no user listorinitial start failed: …. The first wait is 1 second, and it doubles after each failure up to 60 seconds, or up to the node’supdate_periodicwhen that is shorter. An edit to the node’s[[node]]section makes it try again at once. katana does not exit while a node retries, even when that is its only node, so a service manager sees a running process. Nodes lists these errors.
Signals
Section titled “Signals”Neither program has a reload signal. A reload happens when the config file changes on disk.
The handlers for SIGINT and SIGTERM are installed only once startup has finished: in etemenanki-app after every listener is bound, in katana after the nodes have been spawned. A signal that arrives earlier, or during --test, terminates the process at once with the kernel’s default action.
| Signal | etemenanki-app | katana |
|---|---|---|
SIGINT (Ctrl-C) |
Graceful stop, exit 0 |
Graceful stop, exit 0 |
SIGTERM |
Graceful stop, exit 0 |
Graceful stop, exit 0 |
SIGHUP |
Not handled: the process is terminated at once, without a shutting down line |
Same |
SIGKILL |
Terminated at once | Terminated at once; traffic not yet reported to the panel is lost |
A graceful stop logs shutting down, then:
- etemenanki-app cancels the running configuration: it closes every listener and every open connection at once, without waiting for connections to finish, and exits.
- katana cancels every node. Each running node closes its listeners and connections, so its traffic counters are final, and then flushes them to the panel: one last traffic report if any user has unreported traffic and
disable_upload_trafficis off, and one audit report if any audit rule matched. Each request can take up to the node’sapi.timeout, which is 5 seconds when unset or0. If that last report fails, katana logsnode <id>: report traffic: <error>and the traffic is lost, because the counters live only in memory. The process exits when every node has finished.
After the first SIGINT or SIGTERM, the program keeps its handlers, so further SIGINT and SIGTERM signals do not interrupt the stop. Only SIGKILL ends a stop that hangs.
Environment variables
Section titled “Environment variables”Neither program reads an environment variable of its own. The variables below are read by the libraries they are built on.
| Variable | etemenanki-app | katana | Effect |
|---|---|---|---|
RUST_LOG |
yes | yes | The log filter. Replaces [log].level at start when it parses. See Logging. |
NO_COLOR |
yes | yes | Any non-empty value, even 0, removes the ANSI colour codes from log lines. |
TOKIO_WORKER_THREADS |
yes | yes | The number of worker threads of the async runtime. The default is the number of CPUs. A value that is not a positive integer makes the process panic at once and exit with status 101, even with --version. |
SSL_CERT_FILE, SSL_CERT_DIR |
yes | yes | Where TLS clients look for trusted root certificates. See Trusted root certificates. |
HTTPS_PROXY, HTTP_PROXY, ALL_PROXY, NO_PROXY (or lower case) |
no | yes | katana sends its panel requests through the proxy these name, the way curl does. A proxy variable left in a service’s environment therefore also carries the panel traffic. Proxy traffic from users is not affected. |
Trusted root certificates
Section titled “Trusted root certificates”Each TLS client finds the system’s trusted roots in its own way, and SSL_CERT_FILE and SSL_CERT_DIR change each one differently. In all cases, these variables replace a default location rather than add to it. To trust one extra CA for one connection, prefer the ca_file key of that outbound or of [dns]: it adds the CA to the system roots.
| Client | Program | Roots without the variables | With SSL_CERT_FILE or SSL_CERT_DIR set |
|---|---|---|---|
Outbound TLS ([outbound.stream] with security = "tls") and the [dns] tls and https backends |
etemenanki-app | The system OpenSSL library’s default file and directory. On Debian and Ubuntu, these hold the system bundle. | OpenSSL reads the file named by SSL_CERT_FILE instead of its default file, and the directory named by SSL_CERT_DIR instead of its default directory. |
| Hysteria 2 outbound | etemenanki-app | The system bundle, found by probing the usual locations such as /etc/ssl/certs. |
Only the file and directories the variables name are read; the system locations are skipped. SSL_CERT_DIR may list several directories separated by :. If no certificate can be loaded, connections fail with hysteria2: no system root certificates could be loaded, even when the outbound sets ca_file. |
Panel client (api.host over HTTPS) |
katana | The system bundle, found by probing the usual locations. | A variable that names an existing file or directory is used in place of the probed file, and alongside the probed directories. |
The [dns] tls and https backends |
katana | OpenSSL’s built-in default under /usr/local/ssl |
As for etemenanki-app: the variables replace OpenSSL’s defaults. |
Logging
Section titled “Logging”Both programs log to standard output, one line per event, with a UTC timestamp, the level, the module that logged the line and the message. The lines contain ANSI colour codes even when standard output is not a terminal; set NO_COLOR=1 to remove them.
2026-09-24T20:35:11.971456Z INFO etemenanki_app::instance: inbound socks-in listening on 127.0.0.1:10802026-09-24T20:35:13.967835Z INFO etemenanki_app: shutting downThe filter comes from the first of these that applies:
RUST_LOG, if it is set and parses. ARUST_LOGthat does not parse is ignored as a whole. ARUST_LOGthat is set but empty parses as “no directives” and silences every line.[log].levelfrom the config file. If the file cannot be read or parsed, this step is skipped, so the parse error is still printed.info.
Both the variable and the key take the same directive syntax: a comma-separated list where a bare level sets the default and target=level overrides it for one module, for example info,etemenanki_protocols=debug. The targets are the crate names with _ for -: etemenanki_app, katana, etemenanki_protocols, etemenanki_environment and etemenanki_concepts. A single directive in [log].level that cannot be parsed, such as =[, is dropped at start with ignoring `=[`: invalid filter directive on standard error, and the rest applies. If nothing is left, or [log].level is an empty string, only ERROR lines are logged.
katana also applies a changed [log].level on reload. That replaces the filter from RUST_LOG, and a value that does not parse is refused with invalid log level "<value>": <error>. etemenanki-app reads [log].level only at start.
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
level | string | no | "info" | A tracing EnvFilter directive, the same syntax as RUST_LOG: a level (off, error, warn, info, debug, trace, or a number from 0 to 5, case-insensitive), optionally followed by per-target overrides such as "warn,etemenanki_protocols=debug". A RUST_LOG variable that parses as a filter replaces this value, even an empty one, which enables nothing. The value is not validated: a word that is not a level, such as "warning", is read as a target name and silences every log line, errors included. An empty value, or one in which no directive parses, logs errors only. Read once at startup and not applied on reload. |
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
level | string | no | "info" | A tracing EnvFilter directive, the same syntax as RUST_LOG: a level (off, error, warn, info, debug, trace, or a number from 0 to 5, case-insensitive), optionally followed by per-target overrides such as "info,katana=debug". At startup a RUST_LOG variable that holds a valid filter takes precedence. --test does not validate it: at startup an unparsable directive is skipped with an ignoring ... line on stderr, and a word that is not a level, such as "warning", is read as a target name and silences every log line, errors included. A hot reload that changes the value applies it and replaces the RUST_LOG filter; a value that does not parse is logged as invalid log level and the current filter stays. |
Running in production has a table of useful filters and explains how each program handles a changed [log].level at run time.
Messages
Section titled “Messages”These are the lines the process itself prints around startup, reload and shutdown. Messages from the protocols, the panel client and the nodes are described on the pages for those features and on Errors. In the tables, <error> stands for the underlying error text and <tag> for an inbound or outbound tag.
| Level | Message | Meaning |
|---|---|---|
INFO |
inbound <tag> listening on <bind> |
An inbound is up. <bind> is <host>:<port> for TCP, udp <host>:<port> for Hysteria 2, unix:<path> for a Unix socket and tun <name> (or tun auto) for TUN. |
INFO |
inbound <tag> owns tun device <name> |
A TUN inbound created its device. Printed before the listening on line. |
ERROR |
failed to start: <error> |
The start failed. The process exits with 1. A bind error reads failed to start: inbound <tag> bind <bind> failed: <error>. |
ERROR |
config hot-reload disabled: <error> |
The config directory could not be watched. The proxy keeps running, but edits to the file are not applied until a restart. |
INFO |
config reload: <changes> |
A reload is being applied; <changes> summarises what differs. |
ERROR |
reload: cannot read <path>: <error> |
The file could not be read on reload. The current configuration stays. |
ERROR |
reload: parse failed, keeping current config: <error> |
The new file does not parse. The current configuration stays. |
ERROR |
reload: build failed, keeping current config: <error> |
The new file parses but does not build. The current configuration stays. |
ERROR |
inbound <tag> bind <bind> failed: <error> |
On reload, one inbound could not bind. The other inbounds start without it. |
INFO |
shutting down |
SIGINT or SIGTERM was received. |
etemenanki-app hot reload explains the reload lines in detail.
| Level | Message | Meaning |
|---|---|---|
ERROR |
failed to load config: <error> |
The file could not be read or parsed at start. Exit 1. |
ERROR |
failed to build outbounds: <error> |
The [dns] resolver or an [[outbound]] did not build. Exit 1. |
ERROR |
config defines no [[node]] entries |
The file has no [[node]]. Exit 1. |
ERROR |
node <id>: <error> |
At start only: a node’s panel client did not build (for example unknown panel_type "foo"). The node is skipped. |
ERROR |
node <id>: build router: <error> |
At start only: a node’s routing table did not build. The node is skipped. |
ERROR |
no nodes could be started |
Every node was skipped. Exit 1. |
ERROR |
config watcher disabled (no live reload): <error> |
The config directory could not be watched. katana keeps running, but edits to the file are not applied until a restart. |
ERROR |
config reload failed, keeping current: <error> |
The new file could not be read or parsed. |
ERROR |
reload: bad outbounds, keeping current config: <error> |
The new outbound pool did not build. Nothing from the new file is applied. |
ERROR |
reload: node <node>: <error>; keeping current config |
A [[node]] in the new file does not build: the panel client or routing table of a node the reload adds, or the panel client of a node whose settings changed (for example an unknown api.node_type). Nothing from the new file is applied. A node that was skipped at start is built again on each reload, so while it stays broken every reload is refused. |
INFO |
reload: log level → <level> |
[log].level changed. <level> is info when the key was removed. Printed even when the new value was refused with invalid log level. |
ERROR |
invalid log level "<value>": <error> |
The new [log].level does not parse. The current filter stays. |
INFO |
reload: outbound pool rebuilt |
The [[outbound]] list changed and every node now uses the new pool. |
INFO |
reload: removing node <node> |
A [[node]] was removed, or its panel_type, api.host, api.node_id or api.key changed, or, for NewV2board and V2board, the node type it asks the panel for changed (api.node_type other than its letter case, or api.enable_vless on a V2ray or Vmess node). In the second case the node is then added again. |
INFO |
reload: added node <node> |
A new [[node]] was started. |
INFO |
reload: reconfigured node <node> |
Another setting of an existing node changed, and the new settings were sent to it. The node builds a new panel client when an api setting such as api.timeout changed. If the node’s new routing table does not build, it keeps its running settings and logs node <id>: config edit refused, keeping the running one: <error>. |
INFO |
shutting down |
SIGINT or SIGTERM was received. |
<id> is the node’s node_id. <node> is written as <panel_type>@<api.host>#<node_id> with the panel type in lower case. For NewV2board and V2board, katana appends /<node type>, the type it asks the panel for: vless for a V2ray, Vmess or Vless node with api.enable_vless = true, otherwise api.node_type in lower case, for example newv2board@https://panel.example.com#1/v2ray. An SSPanel node has no suffix, for example sspanel@https://panel.example.com#1. katana never writes api.key into these lines.
katana hot reload explains the reload lines in detail, and Troubleshooting covers the per-node messages that follow a start.
Common problems
Section titled “Common problems”| Symptom | Cause | Fix |
|---|---|---|
No such file or directory (os error 2) although the config exists |
A relative path inside the file is resolved against the working directory, or a geodata, certificate or CA file is missing. | Run from the directory the paths are relative to, or use absolute paths. |
--test exits with 1 and prints nothing (etemenanki-app) |
RUST_LOG or [log].level hides ERROR lines. |
Run env -u RUST_LOG etemenanki-app --test -c … and fix [log].level. |
The service stops when you reload it with SIGHUP |
Neither program handles SIGHUP. |
Save the config file instead; it reloads by itself. |
katana passes --test, then a node never comes up |
--test does not contact the panel. The node’s first panel requests or its first start keep failing, and the node keeps retrying. |
Read the node’s retrying in lines in the log and fix the cause. The node comes up at its next attempt, without a restart; see Troubleshooting. |
| Panel requests go to an unexpected host (katana) | A HTTPS_PROXY, HTTP_PROXY or ALL_PROXY variable is set in katana’s environment. |
Remove it, or add the panel host to NO_PROXY. |