When sipnab refuses to start a run, or stops part way through one, it prints a
message. The message says why.
This page lists those messages, so that you can look one up by its text.
Search this page for a distinctive part of the message you see. For example,
search for a flag name or the first few words.
How to read an entry
Each heading is a message exactly as sipnab’s source code writes it.
A name in braces, such as {path}, is a placeholder. sipnab puts a value
there when it prints the message, such as a file name.
A pair of empty braces, {}, is a placeholder without a name.
\n marks a line break.
Under each heading:
the first paragraph says what the message means, and what the placeholders
hold;
What to do says how to get past it;
Exit code is the number sipnab returns to the shell when the message
stops the run.
Exit codes in the CLI reference explains
each code.
An entry marked as a warning does not stop the run.
sipnab prints most messages as log lines on stderr, in this form. stderr is
the standard error stream. A shell shows it on the terminal unless you
redirect it.
2026-10-12T04:04:45.184315Z ERROR sipnab::app::bootstrap: config file not found: /nonexistent/x.toml
The part after the module name (sipnab::app::bootstrap:) is the message.
ERROR lines are errors and WARN lines are warnings.
In the terminal UI, sipnab shows only ERROR lines, unless the SIPNAB_LOG
environment variable sets a level. To see the warnings as well, do one of
these:
run with -N (no terminal UI);
set SIPNAB_LOG=info.
sipnab writes a few messages to stderr without the timestamp and level.
These messages decide the exit code, so they must appear even when logging
is off.
What this page covers
The page lists the messages that the startup and exit path of the sipnab
command raises:
argument checks;
the configuration file;
the run planner, which turns flags and the configuration into a run;
the run modes (batch, terminal UI, the listeners, vCon export, fetch and
forwarding).
It also lists the warnings that these parts of sipnab print while the run
continues.
The page does not list:
the error bodies the REST API returns, which REST API
documents;
the errors the MCP server returns to an agent, which
MCP protocol documents;
errors from the WebAssembly build of the library;
the text of errors that come from deeper inside sipnab or from the
operating system. For example, from the capture code, or from a file sipnab
cannot open.
Startup messages often end with such a text after a colon.
The entry for the startup message explains the part before the colon.
an entry names a message that sipnab no longer prints.
Command-line flags
--alert exec given without --alert-exec <CMD>; no command to run
You gave --alert exec, but no --alert-exec <CMD> (or [security] alert_exec) names the command to run, so the exec alert channel does nothing.
What to do: Add --alert-exec <CMD>, or remove exec from --alert.
Exit code: None. This is a warning, and the run continues.
autostop {key} must be > 0, got 0 (0 stops the capture immediately)
The number in --autostop is 0. {key} is the condition (duration, filesize or the unknown name given). A zero limit would stop the capture immediately. Printed after the prefix Invalid --autostop: .
What to do: Give a number above 0, for example --autostop duration:60.
Exit code: 2.
both --input/-I and --device/-d given: reading the FILE and ignoring the interface. Drop -I to capture live traffic.
A warning: the command line has both -I (read a capture file) and -d (capture from an interface). sipnab reads the file and does not open the interface.
What to do: Remove -I to capture live traffic. Or remove -d to silence the warning when you mean to read the file.
Exit code: None. This is a warning, and the run continues.
--business-hours {reason}
The value given to --business-hours is not a usable working-hours window. {reason} says why. There are two cases:
The value is not two whole hours from 0 to 23 joined by -. The reason then quotes the value.
The start and end hours are equal. That would be a zero-length window, which treats every call as off-hours.
What to do: Give --business-hours as START-END, in whole hours 0-23, with different start and end.
For example, 8-18.
Or 22-6 for a window that crosses midnight.
Exit code: 2.
cannot read suppression file '{name}': {e}
You gave --lint with a suppression file ({name}, from --lint-suppress-file), and sipnab could not read it. The text after the colon is the reason.
What to do: Check the path and its read permission, or pass --lint-no-suppress to lint without suppressions.
Exit code: 2.
cannot read the discovered .sipnablint: {e}
--lint found a .sipnablint file beside the first -I input (or in the -I directory) and could not read or parse it. The text after the colon is the reason.
What to do: Fix or remove that .sipnablint file, name a different one with --lint-suppress-file, or pass --lint-no-suppress.
Exit code: 2.
--capture-tunnels was given an empty port list; drop the flag, or pass ports, e.g. --capture-tunnels={TUNNEL_PORTS_DEFAULT_LIST}
--capture-tunnels takes a comma-separated list of UDP ports. The generated capture filter takes the traffic on these ports in full. It is for tunnels such as GTP-U or VXLAN.
{TUNNEL_PORTS_DEFAULT_LIST} is the default list, 2152,4789,6081.
sipnab checks each port before it reaches this check.
An empty value fails that earlier check first. So a run prints the Invalid --capture-tunnels port message instead of this one.
What to do: Follow the entry for Invalid --capture-tunnels port '{text}': pass one or more ports, for example --capture-tunnels=2152,4789, or remove the flag.
Exit code: 2.
cn-suppression-ratio is a share of the packets and must be a finite number > 0 and <= 1, got {v}
--cn-suppression-ratio takes a share of a stream’s packets: a finite number greater than 0 and at most 1. {v} is the number as read. The value lies outside that range, or is nan or infinite.
What to do: Give a number greater than 0 and no greater than 1, for example 0.5.
Exit code: 2.
--cores {} cannot produce {}: the parallel reader rebuilds dialogs per shard and has no per-message stream or capture writer, so it would emit nothing and still exit 0. Drop --cores for these, or keep --cores and ask for a whole-capture view instead (--json-dialogs, --report, --call-report), which the parallel path does produce.
--cores above 1 with -I (and without --multi-device) uses the parallel file reader.
That reader rebuilds dialogs per shard. It has no per-message output or capture writer.
The first placeholder is the --cores value.
The second lists the requested outputs it cannot produce: --json/--json-pretty, --text-dump, --fail2ban and -O/--output.
sipnab refuses rather than write nothing and exit 0.
What to do: Do one of these:
Remove --cores (or set it to 1) to get those outputs.
Keep --cores and ask for --json-dialogs, --report or --call-report instead.
Exit code: 2.
Expected format 'duration:N' or 'filesize:N', got '{s}'
The --autostop value has no :. {s} is the value given. It must be a condition and a number separated by a colon. Printed after the prefix Invalid --autostop: .
What to do: Use --autostop duration:N (stop after N seconds) or --autostop filesize:N (stop when the output file reaches N MiB), for example --autostop duration:60.
Exit code: 2.
Expected format 'start-end' (e.g., '5060-5061'), got '{s}'
A port range must be two port numbers joined by a single -, such as 5060-5061.
The value shown ({s}) did not split into exactly two parts at -. For example, it is a single port or three numbers.
The same parser reads --portrange, [capture] portrange, --ws-portrange and [capture] ws_ports.
For the first two, the line starts with Invalid --portrange: or Invalid [capture] portrange:.
For the WebSocket pair, it starts with invalid config value: --ws-portrange: or invalid config value: [capture] ws_ports:.
What to do: Write the range as START-END. For one port, repeat it (5060-5060). sipnab accepts a start equal to the end.
Exit code: 2 when the value came from --portrange or --ws-portrange, and 1 when it came from [capture] portrange or [capture] ws_ports.
expected 'plain' or 'hmac', got '{other}'
--hep-auth-mode accepts plain (sipnab sends the HEP shared secret as it is) or hmac (a signed, timestamped token, for sipnab-to-sipnab links only). {other} is the value you gave, in lowercase with surrounding spaces removed. sipnab ignores case and surrounding spaces.
What to do: Give --hep-auth-mode plain or --hep-auth-mode hmac, or leave the flag out for the default plain.
Exit code: 2.
expected 'udp', 'tcp' or 'tls', got '{other}'
--hep-send-transport and --hep-listen-transport choose how HEP (the Homer encapsulation protocol that forwards captured packets) travels: udp, tcp or tls. {other} is the value you gave, in lowercase with surrounding spaces removed.
What to do: Give udp, tcp or tls, or leave the flag out for the default udp.
Exit code: 2.
--fail2ban writes nothing for detections carried by HEP: the inner addresses are the sender's claim, and a jail line would ban whatever address it chose. Pass --hep-allow-kill to admit them once the feed is authenticated (--hep-auth) and trusted.
Startup warning for a run with --fail2ban that reads HEP without --hep-allow-kill.
The run reads HEP with a HEP listener (--hep-listen), or with --hep-parse/-E.
HEP (Homer Encapsulation Protocol) carries copies of SIP packets that another system sent.
The source and destination addresses inside are whatever that sender wrote.
sipnab therefore writes no jail line for a detection that arrived over HEP.
What to do:
If you authenticate the HEP feed (--hep-auth) and trust it, add --hep-allow-kill. Then HEP-carried detections reach the jail log.
Otherwise this warning is normal, and the jail log stays empty for HEP traffic.
Exit code: None. This is a warning, and the run continues.
--fail2ban writes scanner and registration-flood detections, but no detector is running, so this run will emit nothing. An empty jail log means 'nothing was detected', not 'nothing happened'. Add --kill-scanner to detect scanners (offline it only reports; it never transmits), --kill-ua <substring> to match a specific agent, -K/--kill-target <addr> to name one, or --reg-flood to detect registration floods.
Startup warning for --fail2ban when none of the three producers of jail lines is active: no scanner detector (--kill-scanner or [security] kill_scanner), no -K/--kill-target, and no --reg-flood. With none of them, the run cannot write a jail line, so an empty jail log means sipnab looked for nothing.
What to do: Add one of these:
--kill-scanner to detect scanners;
-K/--kill-target <addr> (also addr:port or addr:lo-hi) to name a source;
--reg-flood to detect registration floods.
--kill-ua <pattern> only adds a User-Agent pattern. sipnab accepts it only together with --kill-scanner or [security] kill_scanner = true.
Exit code: None. This is a warning, and the run continues.
Failed to read BPF filter file '{bpf_file}' (--bpf-file): {e}
sipnab could not read the file named by --bpf-file. A BPF filter is the packet filter expression (tcpdump syntax) the kernel applies before sipnab sees packets. {bpf_file} is the path and {e} the reason.
What to do: Correct the path or the file’s permissions, or give the filter expression on the command line instead of --bpf-file.
Exit code: 2.
Failed to start multi-device capture: {e}
--multi-device could not start its captures. {e} is the reason. It is one of these:
the device list given to -d is empty;
the list has an empty entry (a doubled, leading or trailing comma);
the list has a name containing a null byte;
sipnab could not create a capture thread.
What to do: Give -d a comma-separated list of interface names with no empty entries, for example -d eth0,docker0 --multi-device.
Exit code: 1.
{flag} '{}': file is empty
A secret file given with --hep-auth-file or --metrics-auth-file is empty or holds only whitespace. {flag} is the flag, and the quoted value is the path. sipnab refuses to start rather than run without authentication. The line starts with HEP auth: or metrics auth:.
What to do: Write the secret into the file, or remove the flag if you do not want a secret.
Exit code: 2.
--fraud-destination {bad:?} is not a destination sipnab can match: give ISO 3166-1 alpha-2 codes the dial plan labels (NANP for +1 numbers), comma-separated
One entry in the comma-separated --fraud-destination list is not a destination label sipnab knows.
{bad:?} is the first such entry, shown in double quotes.
Labels are the two-letter ISO 3166-1 alpha-2 country codes that sipnab’s dial plan uses. sipnab compares them without regard to case.
Numbers starting with +1 carry the label NANP (North American Numbering Plan). So sipnab does not accept US.
What to do: Replace the named entry with a label from the dial plan, such as GB or DO. Use NANP for any +1 destination. Separate entries with commas.
Exit code: 2.
HEP auth: {e}
sipnab could not resolve the HEP authentication secret. {e} names the source: a --hep-auth-file '<path>' that sipnab cannot read or that is empty, or an empty value in --hep-auth or the SIPNAB_HEP_AUTH environment variable. sipnab refuses an empty secret because it would authenticate any sender that presents an empty one.
What to do: Put a non-empty secret in the file or the flag, or remove --hep-auth/--hep-auth-file and unset SIPNAB_HEP_AUTH.
Exit code: 2.
Ignoring invalid --kill-target '{spec}': {e}
A -K/--kill-target value failed to parse while sipnab built the detectors, and sipnab skips that one target. {spec} is the value, and {e} is the reason. The code notes that this is a fallback: sipnab checks the same values at startup and refuses a malformed value before the capture opens.
What to do: Give the target as ADDR, ADDR:PORT or ADDR:LO-HI. An IPv6 address with a port goes in brackets, for example [::1]:5060.
Exit code: None. sipnab logs the error, and the run continues.
--input/-I and --hep-listen/-L cannot run together. This is a security refusal, not a scheduling one: packets read from a file carry historical addresses belonging to third parties who are not part of this analysis, and sipnab keeps them off the active response path by refusing to transmit for a FILE run at all. A composite source would remove that refusal while the per-packet gate still admitted them. Read the capture in its own run, and point -L at a separate sipnab.
sipnab refuses to read a capture file (-I) and listen for HEP (-L) in one run. HEP is Homer Encapsulation Protocol, a format for mirroring SIP to a collector.
sipnab never transmits during a file run.
Combining the two sources would remove that refusal.
Packets from the file carry other parties’ historical addresses. They could still reach the active response path.
What to do: Run two separate sipnab processes: one that reads the file with -I, and one that listens with -L.
Exit code: 2.
Internal error building the --calls-only filter: {e}
-c/--calls-only keeps only INVITE dialogs. It joins the expression method == 'INVITE' to the run’s filter with AND. That combined expression did not parse.
sipnab has already checked any --filter expression by this point. So this indicates a fault in sipnab.
{e} is the parser’s error.
What to do: Report the message with the command line. Running without -c avoids this step.
Exit code: 2.
--until {} is not after --since {}: the window [--since, --until) would hold no instant
--since and --until keep the dialogs whose first message falls at or after --since and before --until.
The --until time you gave is the first {}.
It is the same as or earlier than the --since time, the second {}.
What to do: Give an --until time later than the --since time. Or drop one of the two flags for a window open on that side.
Exit code: 2.
--since/--until narrow the batch outputs and require -N/--no-tui mode. In the TUI, set the time range in the call list's filter dialog
--since and --until narrow the batch outputs: --report, --json-dialogs, the per-message stream and the queries. The terminal UI shows none of them. You gave one of the flags without -N, so the run would start the terminal UI.
What to do: Add -N to run headless. Or drop the flags and set the time range in the filter dialog of the call list in the terminal UI.
Exit code: 2.
Internal error building diagnostic filter: {e}
sipnab expands the diagnostic alias flags (--problems, --slow-setup, --short-calls, --one-way, --nat-issues) into one filter expression, and that combined expression did not parse. sipnab has already checked any --filter expression by this point, so this indicates a fault in sipnab’s own alias expansion. {e} is the parser’s error.
What to do: Report the message with the command line. Running without the diagnostic alias flags avoids this step.
Exit code: 2.
Invalid {portrange_source}: {e}
sipnab could not parse the SIP port range. {portrange_source} names where it came from: --portrange or [capture] portrange. {e} is the reason: the value is not start-end, a port is not a number from 0 to 65535, or the start is above the end.
What to do: Use the form start-end, for example --portrange 5060-5061, in the flag or the config key.
Exit code: 2 when the value came from --portrange, and 1 when it came from [capture] portrange.
invalid alert rule '{input}': {reason}
An alert rule from --alert or [security] alert does not follow the grammar <name>:<threshold>/<window>[:<cooldown>].
{input} is the rule.
{reason} names the part that failed:
a missing : or /;
an empty name;
a threshold that is not a whole number;
a window or cooldown without an s, m or h suffix.
The line starts with --alert: or [security] alert:.
sipnab reads an entry without : as a channel name, and checks it separately.
What to do: Write the rule as in scanner:10/1m or reg-flood:50/10s:5m: a finding name, a count, /, a window with s, m or h, and optionally : and a cooldown.
Exit code: 2 when the value came from --alert, and 1 when it came from [security] alert.
Invalid --autostop: {e}
sipnab could not use the --autostop value. {e} is the reason. It is one of these:
the value has no :;
the number is not a whole number;
the number is 0;
the condition is not duration or filesize.
What to do: Use --autostop duration:N (seconds) or --autostop filesize:N (MiB), with N a whole number above 0.
Exit code: 2.
Invalid --capture-tunnels port '{text}': expected a comma-separated list of UDP ports in 1-65535, e.g. --capture-tunnels={TUNNEL_PORTS_DEFAULT_LIST}
An entry in the --capture-tunnels list is not a UDP port from 1 to 65535. {text} is the entry as given, after trimming spaces. An empty entry also produces this message. {TUNNEL_PORTS_DEFAULT_LIST} is the default list, 2152,4789,6081.
What to do: Give a comma-separated list of port numbers, for example --capture-tunnels=2152,4789,6081. Or give the flag with no value to use the default.
Exit code: 2.
invalid CIDR '{input}': {reason}
A --hep-allow entry is not a valid address or CIDR range. That flag is the list of senders that may deliver HEP to --hep-listen.
{input} is the entry.
{reason} says what failed:
an invalid IP address;
an invalid prefix length;
a prefix longer than 32 (IPv4) or 128 (IPv6).
The line starts with Invalid --hep-allow CIDR '<entry>':.
sipnab accepts a bare address without /, and reads it as that one host.
What to do: Write each entry as an address (192.0.2.40) or an address with a prefix length (198.51.100.0/24, 2001:db8::/32).
Exit code: 2.
Invalid --duration: {e}
sipnab could not parse the --duration value. {e} is the reason: the value is empty, the number is not a whole number, or the result is too large. The accepted forms are a whole number of seconds, optionally followed by s, m or h.
What to do: Use a form such as --duration 30, --duration 30s, --duration 5m or --duration 1h.
Exit code: 2.
Invalid --duration: '{d}' is zero; give a positive duration
--duration parsed to zero seconds ({d} is the value given). A zero duration would stop the capture before its first packet and exit 0.
What to do: Give a positive duration, for example --duration 30, --duration 30s, --duration 5m or --duration 1h.
Exit code: 2.
Invalid --filter expression: {e}
The --filter expression did not parse. --filter takes sipnab’s dialog filter language, or the name of a diagnostic alias such as problems. {e} is the parser’s error.
What to do: Correct the expression at the point the error names, or use one of the alias names.
Exit code: 2.
Invalid filter pattern: {e}
A SIP matching pattern did not compile as a regular expression. The patterns come from -e/--match, --from, --to, --contact, --ua, or the config file’s [filter] from and [filter] to. {e} names which pattern failed.
What to do: Correct the named pattern’s regular expression syntax, or quote it so the shell passes it unchanged.
Exit code:
2 when the command line includes any of --match, --from, --to, --contact or --ua;
1 otherwise (patterns from the config file).
Invalid --hep-allow CIDR '{cidr}': {e}
A --hep-allow value is not a valid address range. --hep-allow lists the senders the HEP listener accepts, as CIDR notation (an IP address with an optional /prefix length). {cidr} is the value and {e} the reason: an invalid IP, an invalid prefix length, or a prefix longer than the address family allows (32 for IPv4, 128 for IPv6).
What to do: Give an address such as 192.0.2.40 (one host) or a range such as 192.0.2.0/24.
Exit code: 2.
Invalid --ws-portrange: {e}
The SIP over WebSocket port range that --ws-portrange gives is not usable. {e} says what is wrong:
the value is not two ports joined by -;
one side is not a port number from 0 to 65535;
the start is higher than the end.
What to do: Give the range as START-END with the lower port first, for example 8080-8443. Or remove the flag for the shipped ports.
Exit code: 2.
is a MOS and must be at most {}, got {v}
--mos-warn and --mos-bad set MOS (Mean Opinion Score, a call-quality score) boundaries for the quality color column. No score can reach a boundary above the top of the scale. {} is that maximum, 5, and {v} is the value you gave.
What to do: Give a number from 0 to 5.
Exit code: 2.
is a percentage and must be <= 100, got {v}
--duration-asymmetry-pct is a percentage, and the value you gave is above 100. {v} is the value as read.
What to do: Give a number greater than 0 and no greater than 100.
Exit code: 2.
is a percentage and must be at most 100, got {v}
--loss-warn-pct and --loss-bad-pct are packet-loss percentages for the quality color column, and the value you gave is above 100. {v} is the value as read.
What to do: Give a number from 0 to 100.
Exit code: 2.
--kill-target '{spec}': {e}
sipnab could not read a -K/--kill-target value. sipnab checks each value at startup.
{spec} is the value as you gave it.
{e} is the reason, such as:
an empty value;
an address that is not IPv4 or IPv6;
an unclosed [;
a port that is not a number from 0 to 65535;
a port range whose start is above its end.
What to do: Write each value in one of these forms:
an address (192.0.2.10);
an address with a port or port range (192.0.2.10:5060 or 192.0.2.10:5060-5070);
an IPv6 address in brackets, with an optional port ([2001:db8::1]:5060).
Exit code: 2.
--multi-device and --hep-listen/-L cannot run together yet. One interface plus one HEP listener is supported; a device LIST plus a listener is not, because sipnab correlates a HEP-delivered dialog to a locally captured stream by SDP media endpoint alone and that index carries no node dimension — two sources advertising the same address and port would overwrite each other. Drop --multi-device, or drop -L.
You cannot combine --multi-device with a HEP listener (-L). That flag takes a comma-separated device list given to -d.
sipnab matches a HEP-delivered call to locally captured media by the SDP media address and port alone.
With several capture devices, two sources could advertise the same address and port. They would overwrite each other.
sipnab supports one interface plus one HEP listener.
What to do: Remove --multi-device and capture on one interface beside -L, or remove -L.
Exit code: 2.
--multi-device requires a live capture device (-d)
--multi-device opens one capture per network interface in the device list, so it needs a live interface source. This run’s source is not a live interface: it reads a file with -I, or it is a uprobe source (--uprobe-tls/--uprobe-library).
What to do: Name the interfaces with -d, for example -d eth0,docker0 --multi-device, and remove -I and the uprobe flags. Or remove --multi-device.
Exit code: 2.
must be a finite number > 0, got {v}
A diagnosis threshold flag needs a finite number greater than 0. {v} is the value as read, which was 0, negative, nan or infinite. The flags are --pdd-threshold, --ack-timeout, --no-final-response-timeout, --duration-asymmetry-secs and --duration-asymmetry-pct.
What to do: Give a positive number for the flag that the error names.
Exit code: 2.
must be a finite number of 0 or more, got {v}
A measurement boundary or declared delay needs a finite number of 0 or more. {v} is the value as read, which was negative, nan or infinite. The flags are --one-way-delay, --jitter-warn-ms, --jitter-bad-ms, --rtt-warn-ms, --rtt-bad-ms, --mos-warn, --mos-bad, --loss-warn-pct and --loss-bad-pct.
What to do: Give 0 or a positive number for the flag that the error names.
Exit code: 2.
--names {f:?} cannot be read: {e}
sipnab cannot open a file given to --names, or the path is a directory. That flag takes an /etc/hosts-format file that maps IP addresses to names.
{f:?} is the path in quotes and {e} is the reason.
sipnab refuses instead of running without the names you asked it to use.
What to do: Correct the path, make the file readable by the user running sipnab, or remove that --names argument.
Exit code: 1.
no --hep-listen address to plan from
An internal check: sipnab was building the HEP source without a --hep-listen address. Every caller checks for -L first, so this does not happen in normal use. The check exists so that a future change cannot fall back to a default listen address nobody asked for.
What to do: Report the message together with the command line that produced it.
Exit code: 2.
--notes {path}: {refusal}
In a run that starts the TUI, sipnab loads the --notes file before any capture opens and refused it. {path} is the --notes value and {refusal} is the reason: sipnab cannot read the file, a line is not an accepted note, or the file holds more than 10,000 notes. sipnab accepts a file that does not exist yet.
What to do: Correct the line or the permissions the message names, or point --notes at a new file name.
Exit code: 2.
--notes names the notes for --write-annotated or the TUI's notes file, and this run is neither: nothing would read them
--notes names a notes file. Only --write-annotated and the interactive TUI read it.
This run is neither. For example, it uses -N/--no-tui, MCP, or --cores with -I.
So nothing would read the notes, and sipnab refuses the flag.
What to do: Remove --notes, or use it with --write-annotated <OUT> -I <capture>, or in a run that starts the TUI.
Exit code: 2.
Output flags ({}) require -N/--no-tui mode (or --call-report, or --export-vcon)
The flags listed in parentheses print their results to standard output. The interactive terminal interface (TUI) uses standard output. You gave them on a run that starts the TUI.
The list can include --json, --json-dialogs, --json-pretty, --report, --stun, --json-stun, --analyze, --json-analyze, --yang-analyze, --hexdump, --fail2ban, --group-by and --recommend-block.
What to do: Add -N (--no-tui) to run without the TUI. A run with --call-report or --export-vcon is also accepted.
Exit code: 2.
Port range start ({start}) > end ({end})
A port range has a first port larger than the second.
{start} and {end} are the two numbers as read.
The same parser reads --portrange, [capture] portrange, --ws-portrange and [capture] ws_ports.
The line starts with the name of the setting that held the value.
What to do: Put the lower port first, for example 5060-5080 rather than 5080-5060.
Exit code: 2 when the value came from --portrange or --ws-portrange, and 1 when it came from [capture] portrange or [capture] ws_ports.
quality-threshold is a MOS on the 1.0-5.0 scale and must be a finite number in that range, got {v}
--quality-threshold is the MOS (Mean Opinion Score, 1.0 to 5.0) that quality alerts and --on-quality-exec use. {v} is the value as read, which was outside 1.0-5.0, nan or infinite.
What to do: Give a number from 1.0 to 5.0, or leave the flag out for the default 3.0.
Exit code: 2.
Skipping invalid alert rule '{value}': {e}
An --alert (or [security] alert) value containing : is not a valid alert rule, and sipnab skipped it. {value} is the value, and the text after it is the parser’s reason.
What to do: Write the rule as name:threshold/window.
Exit code: None. This is a warning, and the run continues.
start and end must differ; "{start}-{end}" is a zero-width window that would treat every call as off-hours
A business-hours window has the same start and end hour. sipnab uses this window to flag calls placed outside office hours.
{start} and {end} are the two hours.
Such a window has no length, so every call would count as off-hours.
The window comes from one of two places:
--business-hours (the line starts with --business-hours);
[security] business_hours (the line starts with invalid config value: [security] business_hours).
What to do: Give two different whole hours from 0 to 23, such as 8-18, or 22-6 for an overnight window.
Exit code: 2 when the value came from --business-hours, and 1 when it came from [security] business_hours.
{inline_flag}: the value is empty. An empty secret authenticates any peer that presents an empty one, and satisfies the bind policy while doing it -- set a real secret or unset the flag
An inline secret is empty or holds only whitespace. {inline_flag} is --hep-auth (or SIPNAB_HEP_AUTH) or --metrics-auth. An empty secret matches a peer that sends an empty one, and it still counts as configured authentication, so sipnab refuses it. The line starts with HEP auth: or metrics auth:.
What to do: Set a non-empty secret, or unset the flag or environment variable, as the message says.
Exit code: 2.
--tui-audit-file records what an operator did in the TUI, and -N/--no-tui runs no TUI. Use --run-provenance-file to record how a headless run was invoked, or drop -N
--tui-audit-file writes a record of the actions an operator takes in the interactive terminal interface (TUI). -N/--no-tui runs without that interface, so there would be nothing to record. --run-provenance-file records how you started a run, and it works without the TUI.
What to do: Remove -N to run the TUI with its audit file, or replace --tui-audit-file with --run-provenance-file FILE for a headless run.
Exit code: 2.
{from}: Unknown alert channel '{source}': expected one of {}, or a rule written name:threshold/window
sipnab reads an alert source that contains no : as an alert channel name, and {source} is not one. {from} is where the value came from (--alert or [security] alert). The list after “expected one of” is syslog, json, exec (compared without regard to case).
What to do: Use syslog, json or exec as the channel, or write a rule as name:threshold/window, for example scanner:10/1m.
Exit code: 2 when the value came from --alert, and 1 when it came from [security] alert.
Unknown alert channel '{}'. Valid channels: syslog, json, exec. (A value containing ':' is treated as an alert rule.)
sipnab reads an --alert (or [security] alert) value without : as a channel name, and this one is not syslog, json or exec. sipnab ignored it.
What to do: Use syslog, json or exec, or write an alert rule as name:threshold/window.
Exit code: None. This is a warning, and the run continues.
{from}: Unknown alert rule '{}': expected one of {} (reg-flood is accepted for reg_flood)
An alert rule parsed, but its name is not a finding kind any detector produces. {from} is --alert or [security] alert, the first placeholder is the rule name, and the list is digest, fraud, reg_flood, scanner. sipnab accepts reg-flood as another spelling of reg_flood.
What to do: Use one of the listed names in the rule, for example --alert reg_flood:20/1m.
Exit code: 2 when the value came from --alert, and 1 when it came from [security] alert.
Unknown autostop condition: '{key}'. Expected 'duration' or 'filesize'
The --autostop condition name is not one sipnab knows. {key} is the text before the colon. Printed after the prefix Invalid --autostop: .
What to do: Use duration or filesize, for example --autostop duration:60 or --autostop filesize:100.
Exit code: 2.
{from}: {e}
sipnab could not parse an --alert (or [security] alert) rule. {from} names where the rule came from, and the text after it is the parser’s reason.
What to do: Write the rule as name:threshold/window.
Exit code: 2 when the value came from --alert, and 1 when it came from [security] alert in the configuration file.
Configuration file
cannot read config file {path}: {source}
sipnab found a config file but could not read it as text.
The file is one that -f/--config or $SIPNAB_CONFIG names, or one at a default location.
{path} is the file.
{source} is the operating-system or read error. Examples are permission denied, a directory, or content that is not UTF-8.
What to do: Do one of these:
Give the user running sipnab read access to the file.
Point --config at a regular text file.
Start with -F/--no-config to use the built-in defaults.
Exit code: 1.
cannot serialize config: {0}
-D/--dump-config could not turn the loaded configuration back into TOML text. {0} is the serializer’s reason. sipnab logs it as Failed to dump config: cannot serialize config: followed by the reason. --dump-config is the only caller of this conversion.
What to do: The text after the colon is the serializer’s reason. Only --dump-config converts the configuration back to TOML, so this does not affect a run without that flag.
Exit code: 1.
[capture] node_name is empty; give a name, or remove the key for the hostname
The [capture] node_name key holds an empty string. node_name is the name this machine reports in capture_identity.node, and sipnab refuses an empty one. The printed line starts with invalid config value: .
What to do: Write a name between the quotes, or delete the node_name line so sipnab uses the system hostname.
Exit code: 1.
config file not found: {path}
The file that -f/--config names does not exist. {path} is the path you gave. A missing file named by $SIPNAB_CONFIG is not an error: the search moves on to the default locations.
What to do: Correct the path you give to --config, or leave the flag out to use the default search order.
Exit code: 1.
could not load names file {f}: {e}
sipnab could not read a names file when it loaded names. A names file is an /etc/hosts-format file of IP-to-name mappings from --names or [names] hosts_file.
{f} is the path, and {e} is the read error.
Startup already refuses a names file it cannot read. So this appears when the file became unreadable after that check.
The run continues without the names in that file.
What to do: Give the user sipnab runs as read access to the file, and restart sipnab.
Exit code: None. This is a warning, and the run continues.
create {}: {e}
sipnab could not create the folder that holds the configuration file. This happened while saving from the terminal UI, either the column layout (F10 selector) or a name for an address.
{} is the folder path.
{e} is the operating system’s reason.
sipnab writes nothing.
What to do: Create the folder yourself, or give the user running sipnab permission to create it, then save again.
Exit code: None. sipnab shows the error on the terminal UI status line, and the run continues.
[diagnosis] cn_suppression_ratio is a share of the packets and must be a finite number > 0 and <= 1, got {r}
[diagnosis] cn_suppression_ratio is a share of a call’s packets, as a fraction of 1.
That share must be comfort noise before sipnab accepts comfort noise as the reason for one-way audio. Comfort noise is the background-noise packets a phone sends during silence.
The value must be above 0, at most 1, and a finite number (not infinity or NaN, not-a-number).
{r} is the value in the file.
The printed line starts with invalid config value: .
What to do: Set a number above 0 and at most 1, for example the default 0.3, or remove the key.
Exit code: 1.
[diagnosis] duration_asymmetry_pct is a percentage and must be <= 100, got {pct}
[diagnosis] duration_asymmetry_pct is the percentage difference between the durations of a call’s two legs that counts as asymmetric. sipnab refuses values above 100. {pct} is the value in the file. The printed line starts with invalid config value: .
What to do: Set a number above 0 and at most 100, for example the default 5, or remove the key.
Exit code: 1.
[diagnosis] late_media_ms must be > 0, got {ms}
[diagnosis] late_media_ms is how many milliseconds after the 200 OK the media may start before sipnab reports it as late. {ms} is the value in the file, which is 0 or below. The printed line starts with invalid config value: .
What to do: Set a whole number above 0, for example the default 500, or remove the key.
Exit code: 1.
[diagnosis] {key} must be a finite number > 0, got {v}
A [diagnosis] threshold is 0, negative, infinity or NaN (not-a-number).
{key} is one of post_dial_delay_secs, ack_timeout_secs, no_final_response_secs, duration_asymmetry_pct or duration_asymmetry_secs.
{v} is its value.
These thresholds decide when sipnab reports a call as faulty.
The printed line starts with invalid config value: .
What to do: Set the named key to a number above 0, or remove it. The defaults are 11, 32, 180, 5 and 2, in the order listed.
Exit code: 1.
[display] color must be one of {}, got {c:?}
[display] color accepts only auto, always or never, in lowercase. {} is that list, and {c:?} is the value in the file, in double quotes. The printed line starts with invalid config value: .
What to do: Set color to auto, always or never, or remove the key.
Exit code: 1.
[display] from_to must be one of default, host-port, user, user-host-port, got {m:?}
[display] from_to sets how the terminal UI shows the From and To columns. sipnab accepts only default, host-port, user and user-host-port, in lowercase, and {m:?} is the value in the file. sipnab checks this key only in builds that include the terminal UI. The printed line starts with invalid config value: .
What to do: Set from_to to one of the four values, or remove the key.
Exit code: 1.
[display] view_filter_detail must be one of summary, full, got {m:?}
[display] view_filter_detail names a display mode the terminal UI does not have.
{m:?} is the value in the file.
summary shows the filter-dialog (F7) part of the view filter as a short summary on status line 3.
full shows the whole expression.
sipnab checks this key only in builds that include the terminal UI.
The printed line starts with invalid config value: .
What to do: Set view_filter_detail to summary or full, or remove the key.
Exit code: 1.
[display] is not a table
You saved the column layout from the terminal UI (the s action in the F10 column selector). sipnab could not add visible_columns to the configuration file.
The reason: the file defines display as a plain value instead of a [display] table (section).
sipnab writes nothing.
The status line shows Save columns failed: invalid config value: [display] is not a table.
What to do: Edit the configuration file so display is a [display] section, then save again.
Exit code: None. sipnab shows the error on the terminal UI status line, and the run continues.
[display] visible_columns names {col:?}, which is not a column; the columns are {}
[display] visible_columns lists the call-list columns the terminal UI shows.
{col:?} is an entry that matches no column.
{} lists the valid names: #, Method, From, To, Source, Destination, State, Msgs, Date, PDD and Duration.
sipnab compares names without regard to case.
sipnab checks this key only in builds that include the terminal UI.
The printed line starts with invalid config value: .
What to do: Correct or remove the named entry so every entry is one of the listed column names.
Exit code: 1.
Failed to dump config: {e}
--dump-config prints the effective configuration as TOML, and converting the loaded configuration to TOML failed. {e} is the serializer’s error.
What to do: Report the message together with the config file that produced it.
Exit code: 1.
[filter] {key}: {problem}
[filter] from or [filter] to holds a pattern that does not compile.
These keys hold a regular expression (a text-matching pattern). sipnab matches it against the From or To header.
{key} is from or to.
{problem} starts with failed to compile pattern and the pattern. The regular-expression library’s reason follows, such as a syntax error or a pattern over the size limit.
The printed line starts with invalid config value: .
What to do: Correct the pattern so it is a valid regular expression, or remove the key. Characters such as (, [ and + have a special meaning and need a \ before them to match literally.
Exit code: 1.
ignoring invalid [display] from_to = {s:?}
[display] from_to holds a value that names no From/To column mode, and sipnab ignores it. sipnab refuses such a value when it loads the config file, with the message [display] from_to must be one of default, host-port, user, user-host-port. sipnab reaches this warning only for a configuration built without loading a file.
What to do: Set [display] from_to to one of default, host-port, user or user-host-port, or use the matching command-line flag, which takes precedence.
Exit code: None. This is a warning, and the run continues.
ignoring invalid IP key {ip_str:?} in [names.manual]
A key in the [names.manual] table (manual IP-to-name mappings) is not an IP address. So sipnab skips the entry.
{ip_str:?} is the key.
The sipnab command checks this table at startup. It first refuses such a key with invalid config value: [names.manual] key "<key>" is not an IP address (exit 1).
So this warning appears only for a config that reached sipnab::app::build_resolver without that check.
What to do: Write each key as an IPv4 or IPv6 address, for example "192.0.2.5" = "pbx1".
Exit code: None. This is a warning, and the run continues.
ignoring invalid name for {ip_str:?} in [names.manual]
A name in the [names.manual] table is not usable. So sipnab skips the entry.
{ip_str:?} is the IP address the name belongs to.
sipnab refuses a name that:
is empty;
is longer than 253 bytes;
contains a NUL or another control character.
The sipnab command checks this table at startup. It first refuses such a name with invalid config value: [names.manual] name <name> is not a valid name (exit 1).
So this warning appears only for a config that reached sipnab::app::build_resolver without that check.
What to do: Give a non-empty name of at most 253 bytes with no control characters.
Exit code: None. This is a warning, and the run continues.
invalid config {path}: {source}
The config file at {path} is not valid TOML. Or a value has the wrong type for its key, for example text where the key needs a number.
{source} is the TOML parser’s description of the problem.
<inline> appears instead of a path when the text did not come from a file.
What to do: Correct the TOML syntax or the value type that {source} describes, or start with -F/--no-config to skip the file.
The config file’s [filter] expression did not parse as a dialog filter expression or an alias name. sipnab reads it only when the command line has no --filter and no diagnostic alias flags. {e} is the parser’s error.
What to do: Correct [filter] expression in the config file, or remove the key. A --filter given on the command line replaces it.
Exit code: 1.
invalid config value: {0}
The config file parsed as TOML, but a value failed the checks sipnab applies.
{0} names the section and key, and says what is wrong. For example:
a number out of range;
an unknown kind;
an unreadable hosts_file;
a ${NAME} that sipnab cannot expand, which also names the file.
sipnab uses the same wrapper for a malformed --ws-portrange flag value.
What to do: Correct the key that the message names to a value it accepts. The message states the accepted values or range.
Exit code: 1, and 2 when the value came from --ws-portrange.
{key} is empty; give a path, or remove the key for the default
A path-valued key in the configuration file holds an empty string. {key} is the key, for example [hep] tls_ca, [api] tls_cert, [journal] dir, [crash] report_dir or [vcon_forward] ca. An empty path names no file. The printed line starts with invalid config value: .
What to do: Write the path between the quotes, or delete the key so sipnab uses its default.
Exit code: 1.
`${{{name}}}` is not a variable name: expected an ASCII letter or `_` followed by letters, digits or `_`. Shell default-value syntax is not supported
A string in the config file contains ${...}, and its contents are not an environment-variable name.
{name} is the text between the braces.
A name must start with an ASCII letter or _. It continues with letters, digits or _.
sipnab refuses shell forms such as ${VAR:-default}, and an empty ${}.
The full line reads invalid config value: <file>: <dotted.key>: followed by this text. It names the file and the setting.
What to do: Write ${NAME} with a plain variable name. To keep a literal $ in a value, write $$.
Exit code: 1.
`${{{name}}}` is not set in the environment. An unset variable is refused rather than expanded to nothing, because an empty expansion inside a path names a real directory that is not the one intended
A string in the config file uses ${NAME}, and the environment sipnab runs in has no variable of that name. {name} is the variable. sipnab refuses the value rather than substituting an empty string. The full line reads invalid config value: <file>: <dotted.key>: followed by this text, naming the file and the setting.
What to do: Set the variable in the environment that starts sipnab, or replace ${NAME} with the literal value. To keep a literal $, write $$.
Exit code: 1.
[keybindings] {key} = {v:?} is not a key: give one character, a function key (F1-F12) or a named key (Enter, Esc, Tab, Space, Backspace)
A [keybindings] value is not a key the terminal UI can read.
{key} is the action: quit, help, filter, save, search, settings, pause, autoscroll, extended_flow, clear_calls or column_selector.
{v:?} is the value in the file.
sipnab accepts one character, F1 to F12, or Enter, Esc, Tab, Space or Backspace (also in lowercase).
sipnab checks this section only in builds that include the terminal UI.
The printed line starts with invalid config value: .
What to do: Set the named action to one character, a function key such as F5, or one of the named keys. Or remove the line.
Exit code: 1.
[limits] api_max_rows must be > 0 (0 would answer every list request with an empty page)
[limits] api_max_rows is the most rows one list response from the REST API may return. A value of 0 would answer every list request with an empty page, so sipnab refuses it. The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 1000, or remove the key.
Exit code: 1.
[limits] api_rate_limit_per_peer must be at most {} (0 disables the cap), got {v}
[limits] api_rate_limit_per_peer is how many REST API requests one client IP address may make per second. The value is larger than the highest number sipnab can hold for this setting, which {} shows (4294967295). {v} is the value in the file. A value of 0 turns the cap off. The printed line starts with invalid config value: .
What to do: Set a number from 0 to 4294967295, or remove the key for the default of 100.
Exit code: 1.
[limits] exec_queue_depth must be > 0 (it bounds child processes, so there is no unlimited setting; to run no hooks, drop --on-dialog-exec and --on-quality-exec)
[limits] exec_queue_depth is how many hook commands from --on-dialog-exec and --on-quality-exec may run at once before sipnab drops events. A value of 0 has no meaning here, because the setting bounds the number of child processes and has no unlimited value. The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 100. To run no hooks, leave out --on-dialog-exec and --on-quality-exec.
Exit code: 1.
[limits] idle_compact_after_secs must be > 0 (0 would compact dialogs that are still active; to keep more of the ladder, raise this or raise keep_messages_per_idle_dialog)
[limits] idle_compact_after_secs is how many seconds a dialog must stay silent before sipnab compacts it. A dialog is one SIP conversation, such as a call. Compacting keeps only some of its messages.
A value of 0 would compact dialogs that are still active.
The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 600. To keep more of each idle dialog, raise this value or keep_messages_per_idle_dialog.
Exit code: 1.
[limits] lint_max_per_rule must be > 0 (0 would print every repeat of one rule and bury the others)
[limits] lint_max_per_rule is how many findings one lint rule may raise for one dialog. A value of 0 would remove the cap, so one repeating rule could fill the output, and sipnab refuses it. The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 25, or remove the key.
Exit code: 1.
[limits] max_audio_bytes must be >= {} (1 MiB), got {v}; to keep no audio at all, leave --retain-audio off
[limits] max_audio_bytes bounds the audio that --retain-audio keeps across every call.
The value you set, {v}, is below the minimum, {}, 1048576 bytes.
sipnab refuses it rather than read it as “keep nothing”. A budget smaller than one large frame would release every frame it received.
The printed line starts with invalid config value: .
What to do: Set max_audio_bytes to 1048576 or more, or remove the key for the default. To keep no audio, leave --retain-audio off.
Exit code: 1.
[limits] max_capture_sources must be >= 1 (it must hold every capture source a run reads: input files, devices, HEP senders, traced processes)
[limits] max_capture_sources is how many capture sources sipnab remembers by name: each input file, capture device, HEP sender and traced process. A value of 0 leaves no room for even one source. The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 65536, or remove the key.
Exit code: 1.
[limits] max_header_line must be >= 256
[limits] max_header_line is the most bytes sipnab accepts in one SIP header line. The value in the file is below 256, the smallest value sipnab accepts. The printed line starts with invalid config value: .
What to do: Set a value of 256 or more, for example the default 8192, or remove the key.
Exit code: 1.
[limits] max_lost_sequences must be > 0 (0 would retain no losses, so the loss map and the burst/gap analysis would report a lossless call)
[limits] max_lost_sequences is how many lost RTP sequence numbers sipnab keeps for each media stream.
RTP (Real-time Transport Protocol) carries the audio.
The packet-loss map and the burst and gap analysis read these numbers.
A value of 0 would keep none, so every call would look lossless.
The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 1000, or remove the key.
Exit code: 1.
[limits] max_tcp_buffer must be >= {} (a smaller ceiling cannot hold one SIP header line, so every SIP/TCP message would be flushed mid-message and reported malformed), got {v}
[limits] max_tcp_buffer is how many bytes sipnab may buffer for one direction of a SIP over TCP connection, before it flushes the buffer.
{} is the smallest value accepted, 8192. That is the longest single header line the parser accepts.
{v} is the value in the file.
A smaller buffer cannot hold one header line. So sipnab would report every SIP over TCP message as malformed.
The printed line starts with invalid config value: .
What to do: Set a value of 8192 or more, for example the default 65536, or remove the key.
Exit code: 1.
[limits] max_tracked_peers must be >= {} (a map of one turns the per-peer cap into a global lock: the first peer to send in a window takes the only slot and every other peer is refused for the rest of it), got {v}
[limits] max_tracked_peers is how many different peers one rate-limit window may track. Peers are HEP senders and MCP callers.
{} is the smallest value accepted, 2.
{v} is the value in the file.
With room for one peer, the first peer to send in a window would take the only slot. sipnab would then refuse every other peer for the rest of that window.
The printed line starts with invalid config value: .
What to do: Set a value of 2 or more, for example the default 4096. Set at least the number of peers that send to this sipnab.
Exit code: 1.
[limits] mcp_max_body_bytes must be > 0 (0 would answer every body question with a truncation marker and no body)
[limits] mcp_max_body_bytes is how many bytes of SIP body or matched text one MCP response may carry. MCP (Model Context Protocol) is the interface AI assistants use to query sipnab. A value of 0 would replace every body with a truncation marker. The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 4096, or remove the key.
Exit code: 1.
[limits] mcp_max_findings must be > 0 (0 refuses every write; to accept no findings, drop --mcp-allow-save-findings)
[limits] mcp_max_findings is how many findings the MCP save_findings tool accepts before it refuses more. A value of 0 would refuse every write. The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 1000. To accept no findings, leave out --mcp-allow-save-findings.
Exit code: 1.
[limits] mcp_max_wait_seconds must be > 0 (0 would make await_condition answer before it looked, which is a poll spelled expensively)
[limits] mcp_max_wait_seconds is the longest, in seconds, that one MCP await_condition call may wait. A value of 0 would make the call answer before it checked anything. The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 60, or remove the key.
Exit code: 1.
[limits] metrics_max_conn must be > 0 (0 refuses every scrape and the /metrics endpoint answers 503 forever; to serve no metrics, drop --metrics)
[limits] metrics_max_conn is how many scrapes the /metrics endpoint serves at once, before it answers 503. A scrape is a request from a monitoring system such as Prometheus.
A value of 0 would turn every scrape away.
The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 16. To serve no metrics, leave out --metrics.
Exit code: 1.
[limits] {key} must be 1-{max} ({why}), got {v}
A [limits] setting for the MCP find_in_captures sweep is 0 or above its maximum. The sweep is a search across saved capture files.
{key} and {max} are one of:
mcp_sweep_max_files up to 4294967295;
mcp_sweep_deadline_ms up to 43200000;
mcp_sweep_max_running up to 64;
mcp_sweep_max_held_results up to 256;
mcp_sweep_result_retention_secs up to 43200.
{why} says what each end of the range protects.
{v} is the value in the file.
The printed line starts with invalid config value: .
What to do: Set the named key to a whole number from 1 to the maximum shown, or remove the key.
Exit code: 1.
[limits] quality_interval_secs ({secs}) must be between {} and {} (0 would snapshot on every packet; a period wider than the retained hour leaves a trend of one entry)
[limits] quality_interval_secs is how often, in seconds, sipnab records a quality snapshot for each media stream. {secs} is the value in the file, and the two {} are the accepted range, 1 and 300. The printed line starts with invalid config value: .
What to do: Set a whole number from 1 to 300, or remove the key.
Exit code: 1.
[limits] reassembly_ttl_secs must be > 0 (0 evicts every partial on the next sweep and reports both halves as malformed; to turn reassembly off, use --no-reassembly)
[limits] reassembly_ttl_secs is how many seconds sipnab holds an incomplete IP datagram or a half-read TCP stream before a sweep discards it. A value of 0 would discard every partial message on the next sweep, and sipnab would report both halves as malformed. The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 30. To turn reassembly off, use --no-reassembly.
Exit code: 1.
[media.codec_ie] {codec} must be >= 0 and < {} (at or above that the E-model's loss term goes negative and MORE packet loss would RAISE the score), got {ie}
A [media.codec_ie] entry is out of range.
Each entry sets the equipment impairment factor (Ie) for one codec. That factor is the E-model’s measure of how much a codec degrades voice quality.
sipnab uses it in its MOS (mean opinion score) estimate.
{codec} is the codec name.
{} is the upper limit 95.
{ie} is the value in the file.
At 95 or above, more packet loss would raise the score.
The printed line starts with invalid config value: .
What to do: Set the codec’s value to a number of 0 or more and below 95, or remove the entry.
Exit code: 1.
[media] listening_context must be "monotic" or "diotic", got "{lc}"
[media] listening_context says how the far end listened to wideband (AMR-WB) audio, which changes the quality score. sipnab accepts monotic (a handset or one-ear headset) or diotic (a stereo headset or speakerphone), in any case. {lc} is the value in the file. The printed line starts with invalid config value: .
What to do: Set listening_context to monotic or diotic, or remove the key for the default monotic.
Exit code: 1.
[media] one_way_delay_ms must be a finite number of 0 or more, got {ms}
[media] one_way_delay_ms is the one-way network delay, in milliseconds, that sipnab uses for the quality score on this path. The value must be 0 or more and a finite number (not infinity or NaN, not-a-number). {ms} is the value in the file. The printed line starts with invalid config value: .
What to do: Set a number of 0 or more, or remove the key.
Exit code: 1.
{key} must be > 0
A count in the configuration file is 0.
{key} is the key. It is one of:
[capture] snaplen;
[capture] buffer;
the [limits] keys dialog_limit, mcp_max_rows, max_streams, max_reassembly, max_headers_per_message, max_messages_per_dialog, max_audio_frames, keep_messages_per_idle_dialog, max_groups, max_grouped_messages, max_metadata_file_bytes or max_gunzip_bytes.
The matching command-line flags refuse 0 too.
The printed line starts with invalid config value: .
What to do: Set the named key to a whole number of 1 or more, or remove it for the default.
Exit code: 1.
[names] dns_cache_entries must be > 0 (0 evicts on every insert, holding about one entry)
[names] dns_cache_entries is how many reverse-DNS results (names looked up from IP addresses) sipnab keeps at once. A value of 0 would hold about one entry. The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 4096, or remove the key.
Exit code: 1.
[names] hosts_file {hf:?} cannot be read: {e}
sipnab could not open the file named by [names] hosts_file, a file of IP address to name lines in /etc/hosts format. {hf:?} is the path, in double quotes, and {e} is the operating system’s reason, or is a directory when the path names a directory. The printed line starts with invalid config value: .
What to do: Point hosts_file at an existing file that the user running sipnab can read, or remove the key.
Exit code: 1.
[names] is not a table
In the terminal UI you named an address with [names] persist_to_config on. sipnab tried to save the name in the [names.manual] table of the configuration file.
The file defines names as a plain value instead of a [names] table (section). So sipnab writes nothing to it.
The status line shows this text after Named, but couldn't update and the file path.
What to do: Edit the configuration file so names is a [names] section, then name the address again.
Exit code: None. sipnab shows the error on the terminal UI status line, and the run continues.
[names.manual] key {ip:?} is not an IP address
A key in the [names.manual] table, which maps IP addresses to display names, is not an IP address. {ip:?} is the key, in double quotes. The printed line starts with invalid config value: .
What to do: Make each key a single IPv4 or IPv6 address in quotes, for example "192.0.2.1" = "pbx", or remove the entry.
Exit code: 1.
[names.manual] name {name:?} for {ip} is not a valid name
A name in the [names.manual] table is empty, longer than 253 bytes, or contains a control character. {name:?} is the name, in double quotes, and {ip} is the address it belongs to. The printed line starts with invalid config value: .
What to do: Give the address a name of 1 to 253 bytes with no control characters such as tabs or newlines.
Exit code: 1.
not saved: the settings in use come from {SYSTEM_CONFIG_PATH}, and a user file would hide every setting in it. Copy it to ~/.config/sipnab/sipnab.toml to save from the terminal UI
The terminal UI shows this on its status line in this case:
You ask for a save: the F10 column layout, or name edits with [names] persist_to_config.
The settings in use came from the system file /etc/sipnab/sipnab.toml.
sipnab does not write a user file. sipnab reads a user file before the system file, so the user file would hide every setting in it. sipnab saves nothing.
What to do:
Copy /etc/sipnab/sipnab.toml to your user config file. That is ~/.config/sipnab/sipnab.toml, or $XDG_CONFIG_HOME/sipnab/sipnab.toml when that variable holds an absolute path.
Start sipnab so it loads the copy (or with --config naming the copy).
Save again.
Exit code: None. This is a status-line message, and the run continues.
{e}; off-hours fraud detection is OFF for this run
Fraud detection is on, but the business-hours window (--business-hours or [security] business_hours) did not parse.
sipnab turns the off-hours check off for this run. The other fraud checks still run.
{e} is the parse error.
The code notes that startup validation refuses a bad value first. So this line appears only when that validation did not run.
What to do: Give the window as START-END, in whole hours 0-23, with different start and end.
For example, 8-18.
Or 22-6 for an overnight window.
Exit code: None. sipnab logs the error, and the run continues.
Reading {}. Also present and NOT read: {}. sipnab reads only the first config file it finds; merge them or remove the ones you do not want.
More than one default config file exists. sipnab read the first one named and none of the others listed after it.
What to do: Merge the files into one, or remove the ones you do not want.
Exit code: None. This is a warning, and the run continues.
read {}: {e}. Refusing to save, because writing what was merged into an empty file would replace the existing configuration
While saving from the terminal UI, sipnab could not read the existing configuration file.
{} is the file path.
{e} is the operating system’s reason, such as permission denied, or a file that is not UTF-8 text.
sipnab stops instead of saving. Writing into an empty copy would erase your other settings.
A missing file is not an error: sipnab creates it.
What to do: Make the file readable by the user running sipnab, or fix its contents, then save again.
Exit code: None. sipnab shows the error on the terminal UI status line, and the run continues.
[security] business_hours {reason}
[security] business_hours is not a usable working-hours window. {reason} says why. There are two cases:
The value is not two whole hours from 0 to 23 joined by -. The reason then quotes the value.
The start and end hours are the same. That would make every call off-hours.
The hours are UTC. The printed line starts with invalid config value: .
What to do: Write business_hours as "START-END", in whole hours from 0 to 23, with different start and end.
For example, "8-18".
Or "22-6" for a window that crosses midnight.
Exit code: 1.
[security] fraud_destination {bad:?} is not a destination sipnab can match: give ISO 3166-1 alpha-2 codes the dial plan labels (NANP for +1 numbers), comma-separated
One entry in the comma-separated [security] fraud_destination list is not a destination label sipnab knows.
{bad:?} is the first such entry, in double quotes.
Labels are the two-letter ISO 3166-1 alpha-2 country codes from sipnab’s dial plan.
Numbers that start with +1 carry the label NANP (North American Numbering Plan).
The printed line starts with invalid config value: .
What to do: Replace the named entry with a country code from the dial plan, such as GB. Use NANP for any +1 destination. Separate entries with commas.
Exit code: 1.
[security] hep_hmac_window_secs must be 1-{MAX_HEP_HMAC_WINDOW_SECS} (the window is how long a captured packet stays replayable and how many nonces the receiver must remember; a sender more than {MAX_HEP_HMAC_WINDOW_SECS}s adrift has no working time daemon, which is what to fix), got {v}
[security] hep_hmac_window_secs is how many seconds a HEP packet’s signed timestamp may differ from this machine’s clock. It applies when --hep-auth-mode hmac is on. HEP is the protocol capture agents use to send packets to a collector.
The value is 0 or above 300, the maximum that {MAX_HEP_HMAC_WINDOW_SECS} shows.
{v} is the value in the file.
A wider window keeps a captured packet replayable for longer.
The printed line starts with invalid config value: .
What to do: Set a whole number from 1 to 300, or remove the key for the default of 30. If a sender’s clock is off by more than that, fix the time synchronization (for example NTP) on that sender.
Exit code: 1.
[security] kill_rate_limit must be > 0 (it bounds responses sipnab puts on the wire, so there is no unlimited setting; to send none, drop --kill-scanner and -K)
[security] kill_rate_limit is how many scanner-kill responses per second sipnab may send on the network. A value of 0 has no meaning here, because the setting bounds packets sipnab sends and has no unlimited value. The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 10. To send no responses, leave out --kill-scanner and -K.
Exit code: 1.
[security] kill_response must be 100-699, got {code}
[security] kill_response is the SIP status code sipnab sends in a scanner-kill response. SIP status codes run from 100 to 699, and {code} is the value in the file. The printed line starts with invalid config value: .
What to do: Set a code from 100 to 699, or remove the key.
Exit code: 1.
[security] {key} must be > 0
A fraud-detection or scanner-detection count, window or factor in [security] is 0.
{key} is one of fraud_short_call_secs, fraud_sequential_calls, scanner_enumeration_targets, fraud_volume_window_secs, fraud_wangiri_window_secs, scanner_window_secs, scanner_answer_grace_ms, fraud_wangiri_calls, fraud_volume_multiplier, fraud_volume_min_calls, scanner_behavioral_probes, scanner_rejected_probes, scanner_unanswered_probes or scanner_established_factor.
A value of 0 makes a detector report everything or nothing.
The printed line starts with invalid config value: .
What to do: Set the named key to a whole number of 1 or more, or remove it for the default.
Exit code: 1.
[security] reg_flood_threshold must be > 0 (0 would report every REGISTER as a flood; to switch the detector off, drop --reg-flood)
[security] reg_flood_threshold is how many challenged REGISTER failures from one source inside one window sipnab counts before it reports a registration flood. A value of 0 would report every REGISTER as a flood. The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 50. To turn the detector off, leave out --reg-flood.
Exit code: 1.
[security] reg_flood_transaction_timeout_ms must be {MIN_TRANSACTION_TIMEOUT_MS}-{MAX_TRANSACTION_TIMEOUT_MS} (milliseconds; RFC 3261 Timer F is 64*T1, 32000 at the default T1 of 500 ms), got {v}
[security] reg_flood_transaction_timeout_ms is how long, in milliseconds, a REGISTER that carried credentials waits for the challenge that answers it.
The accepted range is 1000 to 600000. The two placeholders show it.
{v} is the value in the file.
RFC 3261 Timer F is 64 times T1. That is 32000 at the default T1 of 500 ms.
The printed line starts with invalid config value: .
What to do: Set a whole number from 1000 to 600000, or remove the key for the default of 32000.
Exit code: 1.
[security] reg_flood_window_secs must be 1-{MAX_WINDOW_SECS} (seconds of capture time one failure count spans), got {v}
[security] reg_flood_window_secs is how many seconds of capture time one registration-flood count spans. The accepted range is 1 to 3600, which {MAX_WINDOW_SECS} shows, and {v} is the value in the file. The printed line starts with invalid config value: .
What to do: Set a whole number from 1 to 3600, or remove the key for the default of 1.
Exit code: 1.
[sip] active_idle_window_secs must be > 0 (0 leaves the active-dialog and active-call gauges permanently at zero, which reads as a quiet trunk rather than as a setting)
[sip] active_idle_window_secs is how many seconds a dialog may go without a message and still count toward two gauges. The gauges are the active-dialog and active-call counters in the metrics output.
A value of 0 would keep both gauges at zero.
The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 3600, or remove the key.
Exit code: 1.
[sip] leg_correlation_window_ms must be > 0 (0 still correlates legs created in the same millisecond; to ignore the guess, read the strategy each correlation is reported under)
[sip] leg_correlation_window_ms is how many milliseconds apart two legs of one call may start for sipnab to still join them on timing alone. sipnab refuses 0 because it does not turn timing correlation off: legs created in the same millisecond still correlate. The printed line starts with invalid config value: .
What to do: Set a whole number of 1 or more, for example the default 2000, or remove the key. To disregard timing-based joins, check the strategy that sipnab reports with each correlation.
Exit code: 1.
sipnabrc is not valid TOML: {e}
While saving from the terminal UI, sipnab found that the existing configuration file is not valid TOML (the configuration file format).
So it cannot update one section and keep the rest.
{e} is the TOML parser’s description of the problem and where it is.
sipnab writes nothing.
What to do: Fix the TOML syntax at the place the error names, then save again.
Exit code: None. sipnab shows the error on the terminal UI status line, and the run continues.
[theme] {key} = {v:?} is not a color: give a name (red, dark_gray, reset, ...) or #rrggbb
A [theme] color is not one sipnab can read.
{key} is the slot: background, foreground, highlight, header, selected, accent, good, warning, bad, muted, border or status_bg.
{v:?} is the value in the file.
sipnab accepts, in any case:
black, white, red, green, yellow, blue, magenta, cyan, gray, dark_gray, reset (and a few alternative spellings);
or # and six hexadecimal digits.
sipnab checks this section only in builds that include the terminal UI.
The printed line starts with invalid config value: .
What to do: Set the named slot to one of the color names, or to a value such as #1e90ff. Or remove the line.
Exit code: 1.
Unknown color value: {s:?}
A [theme] color in the config file is not a color sipnab knows.
It is not a known color name: black, white, red, green, yellow, blue, magenta, cyan, gray or grey, dark_gray and its spellings, reset or default.
It is not a # value of 7 characters.
{s:?} is the value as written.
sipnab logs this warning while it checks the config at startup. The refusal invalid config value: [theme] <key> = "<value>" is not a color: follows it.
sipnab refuses a 7-character # value with non-hex digits without this warning line.
What to do: Use one of the listed names or a #rrggbb hex value for that [theme] key.
Exit code: 1, from the refusal that follows this line.
Unknown config key: {key}
The config file contains a key or a section that sipnab does not recognize. {key} is the name: name for a top-level entry, and section.key inside a known section. sipnab ignores it and keeps running, so the setting has no effect. For an unknown section, sipnab reports the section name and does not list the keys inside it.
What to do: Correct the spelling, move the key into the section it belongs to, or delete it.
Exit code: None. This is a warning, and the run continues.
Unknown keybinding value: {s:?}
A [keybindings] value in the config file is not a key the terminal UI can bind.
{s:?} is the value as written.
sipnab accepts one character, F1 to F12, or a named key (Esc, Space, Enter, Tab, Backspace and their listed spellings).
sipnab logs this warning while it checks the config at startup. The refusal invalid config value: [keybindings] <key> = "<value>" is not a key: follows it.
sipnab refuses a value that starts with F or f but is not F1 to F12. It does so without this warning line.
What to do: For that [keybindings] entry, use one character, a function key from F1 to F12, or one of the named keys.
Exit code: 1, from the refusal that follows this line.
unterminated `${{` in {input:?}
A string in the config file contains ${ with no closing }. {input:?} is the whole string as written. The full line reads invalid config value: <file>: <dotted.key>: ..., naming the file and the setting.
What to do: Close the variable reference (${NAME}), or write $$ where you mean a literal $.
Exit code: 1.
[vcon_fetch] {}: {e}
A whole-number [vcon_fetch] key is out of range. {} is the key (timeout, max_response_head or max_size), and {e} reads N is out of range: give a whole number from MIN to MAX with the value and the limits. timeout accepts 1 to 600 and the other two accept 1 to 4294967295. The printed line starts with invalid config value: .
What to do: Set the named key to a whole number in the range shown, or remove it.
Exit code: 1.
[vcon_fetch] signer_sha256: {e}
[vcon_fetch] signer_sha256 is not a SHA-256 fingerprint.
{e} reads "VALUE": a SHA-256 fingerprint is 64 hex digits, plain or in colon-separated pairs, with the value from the file.
The printed line starts with invalid config value: .
What to do: Set signer_sha256 to the signing certificate’s fingerprint, for example the output of openssl x509 -noout -fingerprint -sha256 -in signing.crt, or remove the key.
Exit code: 1.
[vcon_input] signer_sha256: {e}
[vcon_input] signer_sha256 is not a SHA-256 fingerprint.
{e} reads "VALUE": a SHA-256 fingerprint is 64 hex digits, plain or in colon-separated pairs, with the value from the file.
The printed line starts with invalid config value: .
What to do: Set signer_sha256 to the signing certificate’s fingerprint, for example the output of openssl x509 -noout -fingerprint -sha256 -in signing.crt, or remove the key.
Exit code: 1.
[vcon_fetch] kind: {name:?} is not one of {}
[vcon_fetch] kind names a vCon store type sipnab does not know. A vCon is a standard JSON container for a conversation. {name:?} is the value in the file, and {} lists the accepted names: generic, vcon-store, conserver and vcon-mcp. The printed line starts with invalid config value: .
What to do: Set kind to one of the listed names, or remove the key.
Exit code: 1.
[vcon] encrypt_to is an empty list: name at least one recipient certificate, or remove the key
[vcon] encrypt_to is []. Nobody could open a container encrypted to no recipient, so sipnab refuses the list rather than write one.
The printed line starts with invalid config value: .
What to do: List at least one recipient certificate, or remove the key so that no rule inherits it.
Exit code: 1.
[vcon] compress: {value:?} is not one of {}
The [vcon] section’s compress key names a compression sipnab does not write.
{value:?} is the value in the file.
{} lists the accepted values: none and gzip.
The printed line starts with invalid config value: .
What to do: Set compress to none or gzip, or remove the key.
Exit code: 1.
[vcon] uuid_domain: {value:?} {why}
The [vcon] section’s uuid_domain key is not a fully qualified host name.
{value:?} is the value in the file.
{why} says which rule it breaks: it is empty, it has one label, a label is empty or longer than MAX_UUID_DOMAIN_LABEL (63) characters, the name is longer than MAX_UUID_DOMAIN_NAME (253) characters, it has a character other than an ASCII letter, a digit, a hyphen or a dot, a label starts or ends with a hyphen, or it is an IPv4 address.
The printed line starts with invalid config value: .
What to do: Set uuid_domain to a host name such as node1.pbx.example.com, writing an internationalized name in its xn-- form, or remove the key. See The uuid under a domain.
Exit code: 1.
[vcon_forward] {}: {e}
A whole-number [vcon_forward] key is out of range.
{} is the key.
{e} reads N is out of range: give a whole number from MIN to MAX, with the value and the limits.
The ranges are:
interval accepts 1 to 3600;
timeout 1 to 600;
backoff_first, backoff_cap, max_response_head and max_error_body 1 to 4294967295.
The printed line starts with invalid config value: .
What to do: Set the named key to a whole number in the range shown, or remove it.
Exit code: 1.
[vcon_forward] content_type: {e}
[vcon_forward] content_type names a media type the forwarder does not send for a JSON container.
{e} reads "VALUE" is not one of application/json, application/vcon+json, application/vcon, with the value from the file.
A gzip format container always goes as application/vcon+gzip, so that value is not accepted here.
The printed line starts with invalid config value: .
What to do: Set content_type to one of the listed types, or remove the key for application/json.
Exit code: 1.
{value:?} is not one of {}
The media type given to --vcon-forward-content-type, or to [vcon_forward] content_type, is not one the forwarder sends for a JSON container.
{value:?} is the value given, and {} lists the accepted types: application/json, application/vcon+json and application/vcon.
From the flag, the line starts with error: invalid value and names the flag, and sipnab exits 2.
From the config file, the line starts with invalid config value: [vcon_forward] content_type: , and sipnab exits 1.
What to do: Give one of the listed types, or leave the setting out for application/json. A gzip format container always goes as application/vcon+gzip.
Exit code: 2 from the flag, 1 from the config file.
[vcon_forward] kind: {name:?} is not one of {}
[vcon_forward] kind names a vCon store type the forwarder does not know. A vCon is a standard JSON container for a conversation. {name:?} is the value in the file, and {} lists the accepted names: generic, vcon-store and conserver. The printed line starts with invalid config value: .
What to do: Set kind to one of the listed names, or remove the key.
Exit code: 1.
write {}: {e}
sipnab could not write the configuration file while saving from the terminal UI. {} is the file path and {e} is the operating system’s reason. sipnab writes to a temporary file in the same folder and then renames it, so the existing file stays unchanged.
What to do: Give the user running sipnab permission to write in the folder that holds the file. Check that the disk has free space. Then save again.
Exit code: None. sipnab shows the error on the terminal UI status line, and the run continues.
{display}: {e}
A ${NAME} reference to an environment variable, in a configuration file string, has no value sipnab can use.
{display} is the configuration file path.
{e} is the dotted key path of the setting (for example capture.device, or vcon_forward.ca), followed by : and the reason. The reason is one of these:
the variable is not set;
the ${ has no closing };
the name is not a valid variable name.
sipnab refuses an unset variable instead of replacing it with nothing.
The printed line starts with invalid config value: .
What to do: Do one of these:
Set the named variable in the environment that starts sipnab.
Close the ${.
Correct the name to letters, digits and _, starting with a letter or _.
Write $$ for a literal $.
Exit code: 1.
[capture] ws_ports: {e}
The SIP over WebSocket port range that [capture] ws_ports in the configuration file gives is not usable.
{e} says what is wrong:
the value is not two ports joined by -;
one side is not a port number from 0 to 65535;
the start is higher than the end.
The printed line starts with invalid config value: .
--ws-portrange on the command line replaces the key. sipnab does not read the key when you give the flag.
What to do: Give the range as START-END with the lower port first, for example 8080-8443. Or remove the key for the shipped ports.
Exit code: 1.
[pbx] addresses: '{entry}' is not an IP address or a CIDR range: {e}
An entry in [pbx] addresses is neither an IP address nor a CIDR range. {entry} is the entry and {e} is the parser’s reason. [pbx] addresses lists the PBX’s own addresses, which the filter field side compares against.
What to do: Write each entry as an address (192.0.2.10) or a range (198.51.100.0/24).
Exit code: 1.
[[vcon.rule]] name '{name}' is not usable: a name is 1 to {} ASCII letters, digits, '-' or '_', starting with a letter or digit
A [[vcon.rule]] has a name sipnab cannot use. {name} is the name, and {} is the longest a name may be.
What to do: Use 1 to 64 ASCII letters, digits, - or _, starting with a letter or digit.
Exit code: 1.
[[vcon.rule]] name '{name}' is used by two rules; each rule needs its own
Two [[vcon.rule]] entries have the same name. A rule’s name picks its spool on REST and MCP, so each must be unique.
What to do: Rename one of the rules.
Exit code: 1.
[[vcon.rule]] '{name}' has no dir: say where its containers go
The [[vcon.rule]] named {name} has no dir, so its containers would go nowhere.
What to do: Add dir = "/path/to/spool" to the rule.
Exit code: 1.
[[vcon.rule]] '{name}' has {why}
A key of the [[vcon.rule]] named {name} has a value sipnab does not take. {why} names the key, the value and the values it takes: audio takes inline, url or omit, audio_format takes wav or opus, and grouping takes leg or call.
A sipnab built without the opus Cargo feature refuses audio_format = "opus", and {why} names the feature. The static musl builds do not have it.
What to do: Set the key to one of the values {why} lists.
Exit code: 1.
audio = '{other}'; use 'inline', 'url' or 'omit'
The reason inside [[vcon.rule]] '{name}' has {why} for an audio value other than inline, url and omit. {other} is the value given. See [[vcon.rule]].
What to do: Set audio to inline, url or omit.
Exit code: 1.
grouping = '{other}'; use 'leg' or 'call'
The reason inside [[vcon.rule]] '{name}' has {why} for a grouping value other than leg and call. {other} is the value given. See Calls through a PBX or a B2BUA.
What to do: Set grouping to leg (one container per dialog) or call (one per call).
Exit code: 1.
sealed_updates = '{other}'; use '{}', '{}' or '{}'
The reason inside [[vcon.rule]] '{name}' has {why} for a sealed_updates value other than new-uuid, same-uuid and final-only, which fill the three {}. {other} is the value given. See When an encrypted call changes.
What to do: Set sealed_updates to new-uuid (the default: each change is a new instance with a new uuid), same-uuid (rewrite the file under the same uuid) or final-only (write once, when the call ends), or remove the key.
Exit code: 1.
audio_format = '{other}'; use 'wav' or 'opus'
The reason inside [[vcon.rule]] '{name}' has {why} for an audio_format value other than wav and opus. {other} is the value given. See Audio as Ogg Opus.
What to do: Set audio_format to wav (the default) or opus, or remove the key.
Exit code: 1.
[[vcon.rule]] '{name}' has audio_format without audio = 'inline' or 'url': the rule carries no audio to format
The [[vcon.rule]] named {name} sets audio_format, and its audio is omit or unset.
An omit rule writes no audio, so audio_format would do nothing.
What to do: Remove audio_format, or set audio = "inline" or "url".
Exit code: 1.
[[vcon.rule]] '{name}' has audio = 'url' and no audio_url_base: say where your storage serves the audio files sipnab writes beside the containers
The [[vcon.rule]] named {name} has audio = "url" and no audio_url_base.
A url rule writes each call’s audio file beside its container, and names it by URL.
That needs the base your storage serves the files from.
What to do: Add audio_url_base = "https://...", or use audio = "inline" or "omit".
Exit code: 1.
[[vcon.rule]] '{name}' has audio_url_base '{base}': a vCon names external media over https (draft-ietf-vcon-vcon-core-04 section 2.4.1)
The audio_url_base of the [[vcon.rule]] named {name} is not https://. {base} is the value. A vCon names external media over HTTPS.
What to do: Give an https:// base URL.
Exit code: 1.
[[vcon.rule]] '{name}': 'when' is not a valid filter expression: {e}
The when of the [[vcon.rule]] named {name} does not parse as a filter expression. {e} is the parser’s reason. See Filter DSL.
What to do: Correct the expression. Test it first with sipnab -N -I capture.pcap --filter "...".
Exit code: 1.
[[vcon.rule]] '{name}': '@{reference}' is not a valid filter expression: {e}
The when of the [[vcon.rule]] named {name} references the named filter @{reference}, and its expansion does not parse on its own. sipnab compiles each referenced name by itself to tag a container with the names the call matched. {e} is the parser’s reason.
What to do: Correct that entry in [filters] so it is a complete expression by itself. Test it first with sipnab -N -I capture.pcap --filter "@{reference}".
Exit code: 1.
[[vcon.rule]] '{name}' has {key} = '{header}', which is not a SIP header name: use letters, digits and '-', such as 'X-Queue'
The campaign_header, skill_header or interaction_id_header of the [[vcon.rule]] named {name} is empty or holds a character a SIP header name cannot hold. {key} is the key and {header} the value. Such a name matches no header, and the Dialog parameter would stay empty on every call.
What to do: Write the header name alone, without a colon or a value, such as skill_header = "X-Queue".
Exit code: 1.
[[vcon.rule]] '{name}': no filter
The [[vcon.rule]] named {name} resolved to no filter at all. This is an internal check: a rule’s when always gives one.
What to do: Report it, with the rule as written.
Exit code: 1.
[[vcon.rule]] '{name}': {}
The when of the [[vcon.rule]] named {name} names a filter that does not resolve. {} is why: usually an @name that [filters] does not define, or a [filters] entry that does not resolve.
What to do: Define the name under [filters], or correct the reference.
Exit code: 1.
[[vcon.rule]] with live_audio = true serves call audio on the REST API, and --api {addr} is not a loopback address. Off loopback, live audio needs TLS (--api-tls-cert and --api-tls-key) and a signing key (--api-signing-key or --api-signing-key-file) to mint tokens with the audio scope; or bind --api to 127.0.0.1
A rule with live_audio = true serves call audio on the REST API. --api binds to an address other than loopback, without TLS and a signing key.
What to do: Bind --api to 127.0.0.1, or give --api-tls-cert, --api-tls-key and --api-signing-key-file, and mint the transcriber a token with --token-scope audio.
Exit code: 1.
[[vcon.rule]] '{}' live_rtp = '{}' sends nothing in this run: only a headless run (-N) without --cores forks live audio
A rule names a live_rtp target, and the run is a --cores run or the terminal UI. Neither sends live audio.
The first {} is the rule’s name, the second its target.
What to do: Run with -N and without --cores to send the audio.
Exit code: None. The run continues.
live_rtp: {} datagram(s) could not be sent to their target
At the end of the run, the count of RTP packets and control messages a live_rtp rule could not send. A send fails when the target’s port refuses it, or when the socket stays full for 20 ms.
{} is the count.
The receiver sees a gap in the sequence numbers of a leg that lost a packet.
sipnab sends a service the call as it captured it.
It cannot replace what the service answers, such as a transcript, with pseudonyms.
What to do: Remove --redact, or remove the enrichment from this run.
Exit code: 2.
[limits] idle_compact_after_secs is {secs}, shorter than the {} s a live vCon export waits before it writes a call that has not ended, so idle compaction can drop that call's middle messages before its container is written. Set it to {} or more to keep them.
A live capture exports vCons. [limits] idle_compact_after_secs is shorter than the time a live export waits before writing a call that has not ended.
{secs} is the setting.
The first {} is that wait in seconds. The second is the value to set.
Idle compaction could drop the middle of such a call’s messages before sipnab writes its container.
What to do: Set [limits] idle_compact_after_secs to the value named, or more.
Exit code: None. This is a warning, and the run continues.
Capture and input files
Capture did not complete: {e:#}
The capture thread stopped with an error before it read its whole input. So every report draws on only part of the input.
{e:#} is the full error chain.
The code names these causes:
sipnab could not open the capture;
libpcap rejected the BPF filter (the packet filter);
a read failed fatally;
a filter compiles for the first file of a set, but not for a later one.
What to do: Act on the error text: correct the filter or the file it names. The reports that sipnab printed before the exit are partial.
Exit code: 1.
Capture source failed to open: {e}
The capture source (interface, file or socket) did not open. The text after the colon is the reason.
What to do: Check the device name, file path or address that you gave the run.
Exit code: 1.
Capture thread panicked; the input was not read to the end
The capture thread crashed (a Rust panic) instead of returning.
So sipnab did not read the input to the end.
The reports draw on only part of it.
What to do: This is a crash inside sipnab, not a usage error. Run the command again to confirm it, and report it with the command line and, if possible, the input.
Exit code: 1.
--cores reads capture files in parallel and cannot read the stored vCon container '{}'. Drop --cores: a vCon is read on one core.
--cores reads capture files on several cores, and its readers read packet captures. One of the -I inputs, named by {}, is a stored vCon container, which holds no packets. sipnab refuses the run before it reads anything.
What to do: Drop --cores, or read the vCon container in its own run.
Exit code: 2.
--cores: no capture files to read
The multi-core reader (--cores N with -I) received an empty list of capture files.
The code notes that the normal command line cannot reach this. Input resolution already fails the run when -I resolves to nothing.
The check exists so the run cannot exit 0 with an empty report.
What to do: Pass -I with a capture file, directory or glob that contains at least one readable capture file.
Exit code: 1.
-I/--input: {e:#}
sipnab could not turn the -I/--input values into a list of capture files to read.
{e:#} is the reason with its full chain of causes. For example:
a path that does not exist;
a glob pattern that matched no files;
a directory with no capture files in it;
a pattern that is not valid.
What to do: Correct the path, glob or directory given to -I so that it names at least one readable capture file. The reason after the colon names the value that failed.
Exit code: 1.
multi-core reconstruction failed: {e:#}
The multi-core reader (--cores N) failed. {e:#} is the error chain.
The code returns this error in these cases:
there are no files;
sipnab cannot open the first file of the -I set;
the BPF filter (the packet filter) does not compile against any file in the set.
For a later file that sipnab cannot open, it logs the problem and skips the file instead.
What to do: Act on the error text: make the first file readable, or correct the BPF filter so it applies to every file in the set.
Exit code: 1.
{}\n Available devices: {}\n Try: sipnab -d {}
The run names no capture source, and sipnab could not choose a default interface: there is no non-loopback interface to pick. The first placeholder is the detection error, then the interfaces found and the first of them. On Linux the default is always the any pseudo-device, so this message appears on other systems.
What to do: Name an interface with -d, for example the one the message suggests, or read a file with -I <file>.
Exit code: 1.
No capture device found. Use -d <device> or -I <file>\n Try: sudo sipnab
The run names no capture source (-d, -I, -L, a uprobe flag or [capture] device).
sipnab tried to choose a default interface, and found none. The interface list is empty.
On Linux the default is always the any pseudo-device. So this message appears on other systems.
There, an empty list often means the user lacks capture permission.
What to do: Name a source with -d <device> or -I <file>, or run with sudo so that sipnab can read the interface list.
Exit code: 1.
not a frame pointer: {t}
A shorter form of the malformed frame pointer refusal. {t} is the text.
--show-frame reports a pointer it cannot parse with the longer message. That message starts “not a frame pointer” and continues “expected #”.
The pointer lookup that follows parsing does not return this case.
So the current --show-frame code does not reach this form.
What to do: Give a pointer of the form <source>#<ordinal> or <source>#<ordinal>@<digest>, copied from the frame field of sipnab’s output.
Exit code: 2.
not a frame pointer: {pointer}\nexpected <source>#<ordinal>, optionally #<ordinal>@<digest> — the form the `frame` field of --json-dialogs, --report, REST and MCP emits
The value given to --show-frame is not a frame pointer. {pointer} is the value. A frame pointer is <source>#<ordinal> (the capture and the zero-based frame number), optionally followed by @<digest>. It is the frame field that --json-dialogs, --report, the REST API and MCP print.
What to do: Copy the pointer exactly from the frame field of that output, for example --show-frame capture.pcap#4212@<digest>.
Exit code: 2.
--notes {}: {e}. sipnab will not start the TUI on it
The notes file named by --notes exists, but sipnab cannot use it. So the terminal UI (TUI) does not start.
{} is the path.
{e} says why:
sipnab cannot read the file;
a line (by number) is not a note sipnab accepts;
the file holds more than 10000 notes.
sipnab accepts a path that does not exist yet, and starts an empty notes session.
What to do: Do one of these:
Fix the line the message names.
Reduce the file to 10000 notes or fewer.
Correct the file permissions.
Name a new file with --notes.
Exit code: 2.
refusing: cannot read {source}: {cause}
--show-frame could not open the capture the pointer names.
{source} is the capture path from the pointer (or <archive>/<member> for a capture inside an archive).
{cause} is the reason. For example, a missing file, a file that is not a capture, or an archive with no member of that name.
What to do: Run the command from the directory the pointer’s path is relative to. Or make sure the capture still exists at that path and is readable.
Exit code: 1.
refusing: {source} frame {ordinal} is not the frame this pointer was made against. The capture was rotated, truncated or rewritten since then. Showing you what is there now would look like an answer and be the wrong one.
The frame at position {ordinal} in {source} does not match the digest that sipnab recorded when it made the pointer. The digest is the checksum after @ in the pointer.
So someone or something has rotated, truncated or rewritten the capture since.
sipnab refuses to show a different frame.
What to do: Find the original, unchanged capture that the pointer came from, or produce a new pointer from the current capture.
Exit code: 1.
refusing: {source} holds {frames_present} frame(s), so there is no frame {ordinal}
The capture {source} holds {frames_present} frames, so the frame number {ordinal} in the pointer does not exist. Frame numbers start at 0. The capture may have lost frames to truncation since sipnab made the pointer.
What to do: Check that the pointer names the right capture. Check that the capture is the complete file that the pointer came from.
Exit code: 1.
refusing: read {ordinal} came from the TLS library inside {comm} (pid {pid}). sipnab read it out of the process, so it was never a frame on any wire — there is no capture to seek into and nothing to verify these bytes against.
The pointer given to --show-frame names data that sipnab read through a uprobe. It is not a frame in a capture file. sipnab read the data from inside a running program’s TLS library.
{ordinal} is the read number.
{comm} is the program’s name and {pid} its process ID.
There is no capture to read the bytes from.
What to do: None for this pointer. To see the bytes again, use the output of the run that captured them (for example its JSON output).
Exit code: 1.
unknown password encoding '{s}'; use utf-8, cp437, cp850 or cp1252
--archive-password-encoding names the one text encoding that sipnab tries archive passwords in. {s} is the value you gave. sipnab accepts utf-8 (or utf8), cp437 (ibm437), cp850 (ibm850) and cp1252 (windows-1252), in any case, and reads _ as -.
What to do: Give one of the accepted encodings, or leave the flag out to try the password in all of them.
Exit code: 2.
Output files and exports
{flag}: the answer did not serialize: {e}
A query flag, named by {flag}, computed its answer, and sipnab could not write that answer as JSON or as a table. {e} is the serializer’s reason. This indicates a fault in sipnab.
What to do: Report the message with the command line. Running without --json writes the answer as a table instead.
Exit code: 1.
analysis serialization failed: {e}
--json-analyze prints the capture analysis as one JSON line, and converting the analysis to JSON failed. {e} is the serializer’s error. The code comment calls this a bug in the analysis type. sipnab prints no --json-analyze line.
What to do: Use --analyze for the same analysis as a table.
Exit code: None. sipnab logs the error, and the exit status does not change.
Call-ID '{call_id}' not found in tracked dialogs
--call-report <CALL-ID> asks for a detailed report of one call, and this run tracked no dialog with that exact Call-ID. The match is exact and case-sensitive. The run exits 1, and sipnab produces none of the later reports.
What to do: Run with --report (or --json-dialogs) to list the Call-IDs this run holds, then pass one of them exactly. The text --report table shortens Call-IDs to 30 characters, and --markdown shows them in full.
Exit code: 1.
Cannot emit --tshark-filter command: {e}
--tshark-filter <EXPR> prints a ready-to-paste tshark -r <file> -Y <EXPR> command. sipnab could not name one file for -r.
{e} is the reason. It is one of these:
there is no -I file and no -O file (a live capture that saved nothing);
the input is a member of an archive;
the input is several files.
sipnab prints no command, and the run continues.
What to do: Use a single capture file with -I, or save a live capture with -O <file>. For an archive member, extract it first and run on the extracted file. For several files, run once per file.
Exit code: None. sipnab logs the error, and the run continues.
could not publish evidence
--evidence-out writes one JSON line per security finding that names a source.
- means standard output. Any other value names a file that sipnab opens for append.
Writing one line failed.
The log line carries src_ip (the source the finding is about) and error (the write or serialization error).
The evidence output lacks that finding. Its alert still runs.
What to do: Check that the --evidence-out file accepts writes, and that its disk has space. Or check that the reader on the other end of standard output is still running.
Exit code: None. This is a warning, and the run continues.
--evidence-out {target}: {e}
sipnab could not open the file named by --evidence-out, where it appends one line per security finding. {target} is the path as you gave it, and {e} is the operating system’s reason. sipnab opens the file in create-and-append mode before it reads the first packet. The value - means standard output, and sipnab does not open it as a file.
What to do: Name a path whose directory exists, and that the user sipnab runs as can create or append to. Or pass - to write the findings to standard output.
Exit code: 2.
Failed to write DSB: {e:#}
This applies with --pcap-export-mode encrypted+dsb, --keylog <file> and --pcapng.
sipnab then embeds the TLS key log in the -O output as a Decryption Secrets Block (DSB). So Wireshark can decrypt the file.
Writing that block to the output file failed.
{e:#} is the writer’s error.
The capture continues, and the file has no embedded keys.
What to do: Check free space and write access for the -O location. To decrypt the file later without the block, open it in Wireshark together with the same key log file.
Exit code: None. This is a warning, and the run continues.
Failed to write name resolution block: {e:#}
This applies with --pcapng and name resolution on (--resolve, --reverse-dns, or the [names] settings).
sipnab then writes a Name Resolution Block at the start of the -O file. That block is a table of address-to-name entries.
Writing that block failed.
{e:#} is the writer’s error.
The capture continues without the block.
What to do: Check free space and write access for the -O location.
Exit code: None. This is a warning, and the run continues.
Failed to write output: {e}
Writing the per-message output to standard output failed, for a reason other than a closed pipe. The per-message output is the printed messages, --json lines and similar.
{e} is the error.
The output is incomplete, so the run exits 1.
sipnab does not count a closed pipe, such as | head, as an error.
What to do: Check that the destination of standard output has space and accepts writes. The destination is a file or disk you redirected it to.
Exit code: 1.
Failed to write packet: {}
sipnab could not write a packet to the -O capture file. {} is the writer’s error. When the cause is a permission refusal after sipnab dropped privileges, the message adds the user name and the remedies. In a headless run the capture loop stops, sipnab prints the reports, and the run exits 1. In the TUI the packet-processing thread stops.
What to do: Check free space and write access for the -O location.
If the message names a user that sipnab dropped privileges to, do one of these:
give that user write access to the directory (for example install -d -o <user> <dir>);
pass --user <name> for a user that can write there;
pass --no-priv-drop.
Exit code: 1 in a headless run. In the TUI, this path sets no exit code.
Failed to write report: {e}
sipnab could not write an end-of-run report to standard output.
The reports are --report, --json-dialogs, --stun, --json-stun, --analyze, --json-analyze, --yang-analyze, --hep-senders, or --export-vcon to standard output.
{e} is the error.
sipnab does not count a closed pipe as an error.
sipnab produces none of the reports after the failed one.
What to do: Check that the destination of standard output has space and accepts writes. The destination is a file or disk you redirected it to.
Exit code: 1.
--hep-senders: the roster did not serialize: {e}
--hep-senders with --json prints the sender roster of the HEP listener as one JSON object. The roster says who sent HEP to this run, who went silent, and whom sipnab refused.
Converting that roster to JSON failed.
{e} is the JSON serializer’s error.
The run then exits.
What to do: Run without --json to get the same roster as a text table.
Exit code: 1.
No SIP dialogs to generate Wireshark filter for.
--wireshark prints a Wireshark display filter that selects every tracked call by Call-ID. This run tracked no SIP dialogs, so there is no filter to print.
What to do: Check that the input or interface carries SIP. If the run summary shows a NOT ANALYZED line, apply the --portrange or --ws-portrange change it names.
Exit code: None. This is a warning, and the run continues.
--notes {notes_path}: {e}
--write-annotated could not load the notes file named by --notes ({notes_path}). {e} says why:
sipnab cannot read the file;
a line is not a note sipnab accepts. The message gives its line number. One bad line refuses the whole file;
the file holds more than 10,000 notes.
What to do: Correct the path or permissions, or fix the line the message names, then run the command again.
Exit code: 1.
--notes {notes_path} holds no notes, so there is nothing to annotate
--write-annotated read the notes file named by --notes ({notes_path}) and found no notes in it (sipnab skips blank lines). A copy with no comments added would be identical to the input, so sipnab writes nothing.
What to do: Add notes to the file (for example from the TUI), or name a notes file that contains them. Then run the command again.
Exit code: 1.
-O/--output cannot write a run that captures from two sources. '{out}' would be initialized from whichever member's first packet arrived first, and the two disagree about the link layer: the interface yields Ethernet frames, while HEP delivers a bare SIP payload with no link, IP or transport header to write. Capture the interface alone to write a pcap, or use --hep-send <ADDR> to forward the signaling to a collector instead of writing it.
-O/--output writes a capture file. This run captures from two sources at once:
a live interface (-d or the config file’s device);
a HEP listener (-L).
The interface delivers Ethernet frames. HEP delivers bare SIP text with no link, IP or transport header. So one file cannot hold both. {out} is the -O path.
What to do: Do one of these:
Capture the interface alone (without -L) to write a pcap.
Keep both sources, and use --hep-send <ADDR> to forward the signaling to a collector instead of -O.
Exit code: 2.
Output file may be incomplete: {e:#}
At the end of the run, the final flush of the -O capture file failed. So the end of the file may be missing.
{e:#} is the error chain.
In a headless run the exit code is 1.
What to do: Check free space and write access for the -O location, and treat the file as truncated.
Exit code: 1 in a headless run. In the TUI, this path sets no exit code.
plugin {}: {e}
sipnab could not load a --plugin file.
{} is the path.
{e} is the reason:
sipnab could not read the file;
the file is not valid WebAssembly;
it lacks a required export;
it reports an ABI version this build does not support.
The run still produces its reports. They carry a marker naming the failure. The run exits 1.
What to do: Correct the path, or rebuild the plugin against the plugin ABI version this sipnab build reports.
Exit code: 1.
plugin {} on {}: {e}
A --plugin (a WebAssembly analysis module) failed while it analyzed one dialog for --json-dialogs.
The first {} is the plugin name. The second is the Call-ID.
{e} is the reason. For example, the plugin trapped, ran out of its limits, or returned output in the wrong shape.
sipnab prints that dialog’s line without this plugin’s findings.
What to do: Check the plugin that the message names against the dialog it names. The error text says which kind of failure occurred.
Exit code: None. sipnab logs the error, and the run continues.
--print-yang-module: {e}
--print-yang-module writes the YANG module text (the data model sipnab’s RFC 7951 JSON export follows) to standard output, and the write failed. {e} is the error, for example a pipe whose reader has already closed.
What to do: Make sure standard output is writable, for example redirect it to a file: sipnab --print-yang-module > sipnab.yang.
Exit code: 1.
RFC 7951 encoding failed: {e}
--yang-analyze prints the capture analysis encoded as RFC 7951 JSON (the JSON encoding of YANG-modeled data) against the sipnab-diagnosis model. Encoding failed. {e} is the reason. The code describes this as a mismatch inside sipnab between the analysis and its YANG table. sipnab prints no --yang-analyze line.
What to do: Use --json-analyze for the same analysis as plain JSON, or --analyze for the table.
Exit code: None. sipnab logs the error, and the exit status does not change.
--strip-secrets failed: {e}
--strip-secrets writes a copy of a pcapng capture with every Decryption Secrets Block removed. That block stores TLS keys inside a pcapng file. The copy failed.
{e} is the reason:
sipnab cannot read the input;
the input is larger than the in-memory size limit;
it is not pcapng;
a block has a truncated or invalid length;
sipnab cannot write the output.
sipnab never modifies the input file.
What to do: Act on the reason given. For a file over the size limit, raise --max-metadata-file-bytes or [limits] max_metadata_file_bytes. A classic pcap has no secrets blocks to strip.
Exit code: 1.
--strip-secrets requires an input file (-I <file>)
--strip-secrets <OUT> copies one input capture, and the command line names no input.
What to do: Name the capture to copy with -I, for example sipnab --strip-secrets clean.pcapng -I capture.pcapng.
Exit code: 1.
the input '{}' is a member of an archive, and `tshark -r` reads one capture file; extract that member and point tshark at it
Part of the Cannot emit --tshark-filter command: message. The single input is a file that sipnab extracted from an archive and deletes after the run. tshark -r cannot read inside an archive, so sipnab prints no command. '{}' names the member.
What to do: Extract that member from the archive. Then point tshark at the extracted file, or run sipnab with -I on the extracted file.
Exit code: None. sipnab logs the error, and the run continues.
the input is {} files and `tshark -r` reads one, so no single command covers this run. The display filter below names Call-IDs from all of them; a command reading only one would silently return a subset. Files: {}
Part of the Cannot emit --tshark-filter command: message. The input is several files, and tshark -r reads one, so no single command covers the run, and sipnab prints none. The first {} is the number of files, and the second lists them.
What to do: Run sipnab once per file to get one command per file, or merge the files into one capture first.
Exit code: None. sipnab logs the error, and the run continues.
--tui-audit-file {path}: {e}. sipnab refuses to run the TUI without the action trail it was asked for
sipnab could not open the file named by --tui-audit-file for appending. sipnab does not run the TUI without the record of operator actions you asked for. {path} is the path given, and {e} is the operating system error. sipnab opens the file in append mode and creates it with mode 0600 if it does not exist.
What to do: Name a path in a directory that exists and that the sipnab user can write. Or fix the permissions of the existing file.
Exit code: 2.
--write-annotated needs --notes <FILE>
--write-annotated writes a copy of a capture with notes added as packet comments. The notes come from the file named by --notes.
The command line has no --notes.
The command-line parser normally refuses this combination first. This check is a second guard.
What to do: Add --notes <FILE> naming the notes file.
Exit code: 2.
--write-annotated refused: {e}. Nothing was written to {out}.
sipnab did not write the annotated copy.
{e} is the reason.
{out} is the output path. sipnab left no file there.
The reasons include the following:
The output name ends in a classic pcap extension. Classic pcap has no comment field.
A note’s frame pointer has no @<digest>, names another capture, or names text that sipnab read through a uprobe.
The capture holds fewer frames than a note names.
A frame no longer matches its digest.
sipnab cannot represent a frame timestamp.
sipnab cannot read the capture, or cannot write the copy.
What to do: Act on the reason given.
Name the output .pcapng.
Take frame pointers from --json output over the same capture. They end in @<digest>.
Annotate one capture per run, against the unchanged capture that you wrote the notes for.
Exit code: 1.
--write-annotated requires an input capture (-I <file>)
--write-annotated copies one input capture, and the command line has no -I.
What to do: Name the capture with -I, for example sipnab --notes notes.jsonl --write-annotated out.pcapng -I capture.pcapng.
Exit code: 1.
--write-annotated {out} would overwrite the notes file it reads; name another output
The output path given to --write-annotated ({out}) is the same file as the notes file it reads. It has the same spelling, or is the same file after resolving links. Writing it would destroy the notes.
What to do: Give --write-annotated a different output path.
Exit code: 2.
{flag} writes {}, but -I resolved to {} files: {names}. {}
--strip-secrets and --write-annotated each write one output file from one input capture. Here -I resolved to several files. That flag accepts directories, globs and repeated paths.
{flag} is the command.
The next placeholder is what it writes. Then comes the file count.
{names} is the resolved files.
The last placeholder is the advice.
sipnab refuses rather than handle only the first file.
What to do: Run the command once per capture, giving -I a single file each time.
Exit code: 1.
Servers: REST API, metrics and MCP
actions are off for this run: {why}
sipnab switched actions off for this run because it found damage in the actions journal. Actions are bans and unbans that sipnab asks TFPS, a firewall service, to apply. --allow-action enables them. {why} names the journal file, the record number and what does not match. Everything that only reads keeps working.
What to do: Inspect the journal file the message names, in the directory given by --journal-dir or [journal] dir (default /var/lib/sipnab/journal). Actions stay off until an operator has looked at it.
Exit code: None. sipnab logs the error, and the run continues with actions off.
actions journal: {} action(s) from the last run are still in doubt because TFPS could not be asked; new actions are refused until they are resolved
The actions journal records actions from the previous run whose result is unknown. For example, sipnab stopped while it was sending a ban.
sipnab could not ask TFPS about them at startup.
{} is how many.
sipnab refuses new bans and unbans until TFPS answers.
What to do: Make TFPS reachable at the address in the sipnab configuration. sipnab asks TFPS again once a minute and resolves the actions when it answers.
Exit code: None. This is a warning, and the run continues.
actions: the check against TFPS could not start: {e}
sipnab could not create the thread that checks the actions journal against TFPS once a minute, so sipnab refuses the run. {e} is the operating system error.
What to do: Act on the operating system reason in {e} and run again. Or run without --allow-action, so that sipnab starts no check thread.
Exit code: 2.
Failed to build the shared server runtime: {e}
The thread that runs the REST API and MCP servers could not create its async runtime, so none of those servers run. {e} is the error from the runtime builder. sipnab bound the listeners before this point, and the rest of the run continues.
What to do: The message carries the operating system’s reason in {e}. The code offers no setting that changes this step. Address that reason, then restart the run.
Exit code: None. sipnab logs the error, and the run continues without the REST API and MCP servers.
Failed to create HEP sender: {e:#}
sipnab could not set up the connection that --hep-send uses. That connection forwards captured packets in HEP (Homer Encapsulation Protocol) format.
{e:#} is the reason with its full chain of causes:
the destination address did not resolve;
sipnab could not bind a local UDP socket;
there is no route to the destination;
the TCP or TLS connection failed;
for --hep-send-transport tls, the destination has no host name to check the certificate against.
The run stops instead of running without forwarding.
What to do: Correct the --hep-send address (HOST:PORT), or the transport flags named in the reason. Make sure the collector is reachable from this host.
Exit code: 2.
Failed to spawn the servers thread: {e}
The operating system refused to create the thread that runs the REST API and MCP servers. {e} is the operating system error.
What to do: Act on the operating system reason in {e} and run again. Or run without --api and --mcp, so that sipnab starts no servers thread.
Exit code: 2.
Failed to start metrics server: {e}
The Prometheus metrics endpoint that you asked for with --metrics could not start. {e} gives the reason:
the address is not a loopback address, and you gave no --metrics-auth or --metrics-auth-file;
or sipnab could not bind the port, for example because another program uses it;
or sipnab could not create the server thread.
What to do: Bind to 127.0.0.1, or supply --metrics-auth or --metrics-auth-file for a routable address. Choose a free port, or remove --metrics.
Exit code: 2.
Invalid --api address: {e}
The value of --api is not an address sipnab can listen on. {e} repeats the value and the parse error. sipnab accepts a port (8080), :port, or address:port (127.0.0.1:8080, [::1]:8080).
What to do: Give --api a port or an address:port value, for example --api 127.0.0.1:8080.
Exit code: 2.
invalid bind address '{input}': {reason}
sipnab could not parse a listener address for --api, --metrics or --mcp-bind.
{input} is the value.
{reason} repeats it with the parser’s error.
sipnab accepts:
a port (8080);
:port (both bind 127.0.0.1);
address:port, such as 0.0.0.0:8080 or [::1]:8080.
The line starts with Invalid --api address:, Invalid --metrics address: or Invalid --mcp-bind address:.
What to do: Give the address in one of the accepted forms, with a port from 0 to 65535.
Exit code: 2.
Invalid --mcp-bind address: {e}
The value of --mcp-bind (the listening address for MCP over HTTP) is not an address sipnab can listen on. {e} repeats the value and the parse error. sipnab accepts a port, :port, or address:port. The default is 127.0.0.1:8731.
What to do: Give --mcp-bind a port or an address:port value, for example --mcp-bind 127.0.0.1:8731.
Exit code: 2.
Invalid --metrics address: {e}
sipnab could not parse the --metrics address (where the Prometheus metrics server listens). {e} repeats the value and the reason. The accepted forms are a port number (9090), :port (both bind 127.0.0.1), or a numeric IP:port. sipnab does not accept host names.
What to do: Use a form such as --metrics 9090, --metrics :9090 or --metrics 0.0.0.0:9090.
Exit code: 2.
--journal-show and --revert-actions need the 'api' or 'mcp' feature (not compiled in): no action can have been taken
--journal-show and --revert-actions read the journal of actions that the REST API or MCP server took.
This sipnab build does not include the code for them.
So there is no journal, and this build cannot have taken any action.
What to do: Use a sipnab build compiled with the api or mcp feature on a Unix system, or remove the flags.
Exit code: 2.
--mcp-audit-file {path}: {e}. sipnab refuses to serve MCP without the audit trail it was asked for
sipnab could not open the file named by --mcp-audit-file for appending.
sipnab does not start MCP without the record of tool calls you asked for. MCP (Model Context Protocol) is the interface AI assistants use to query sipnab.
{path} is the path given.
{e} is the operating system error.
sipnab opens the file in append mode. It creates it with mode 0600 if it does not exist.
What to do: Name a path in a directory that exists and that the sipnab user can write. Or fix the permissions of the existing file.
Exit code: 2.
--mcp-tls-cert/--mcp-tls-key serve MCP over HTTPS and do nothing without --mcp --mcp-transport http
--mcp-tls-cert and --mcp-tls-key are the certificate and private key that the MCP (Model Context Protocol) server presents when it serves over HTTP. They make it HTTPS.
You gave at least one of them.
But the run does not serve MCP over HTTP. Either --mcp is absent, or --mcp-transport is not http (the default is stdio).
What to do: Add --mcp --mcp-transport http, or remove --mcp-tls-cert and --mcp-tls-key.
Exit code: 2.
--mcp-token-file '{path}': {e}
sipnab could not read the file named by --mcp-token-file. The file holds the static token that MCP over HTTP accepts. {path} is the path given, and {e} is the operating system error. sipnab reads the file only when you do not give --mcp-token.
What to do: Correct the path or the file permissions, or pass the token with --mcp-token or the SIPNAB_MCP_TOKEN environment variable instead.
Exit code: 2.
--mcp-transport http requires the mcp-http feature; rebuild with --features mcp-http (or full).
You gave --mcp-transport http, but this sipnab binary does not include the mcp-http build feature, so it cannot serve MCP over HTTP.
What to do: Use --mcp-transport stdio, or use a build that includes the mcp-http feature (for example one built with --features mcp-http or --features full).
Exit code: 2.
--mcp uses stdout for the JSON-RPC wire and cannot be combined with stdout-writing flags ({})
--mcp starts the MCP (Model Context Protocol) server, and with the default stdio transport its JSON-RPC messages travel on standard output. The flags listed in parentheses also write to standard output, and sipnab refuses them alongside --mcp. The list includes --export-vcon only when you did not give --vcon-out.
What to do: Remove the listed flags from the --mcp run. For --export-vcon, add --vcon-out FILE so that sipnab writes the container to a file instead of standard output.
Exit code: 2.
metrics auth: {e}
sipnab could not resolve the metrics endpoint credential. {e} says why: sipnab cannot read the file named by --metrics-auth-file, the file is empty, or --metrics-auth has an empty value. sipnab refuses to start the endpoint rather than run it without the authentication you asked for.
What to do: Correct the path or permissions of --metrics-auth-file, put the credential in it, or give --metrics-auth a non-empty value. To run without authentication, remove both flags and bind --metrics to a loopback address.
Exit code: 2.
metrics TLS: {e:#}
sipnab could not set up HTTPS for the metrics endpoint. {e:#} gives the reason:
you gave only one of --metrics-tls-cert and --metrics-tls-key;
sipnab cannot read a file;
the certificate file holds no certificate;
the key file holds no private key;
other users can read the key;
the key does not belong to the certificate.
What to do:
Give both --metrics-tls-cert and --metrics-tls-key.
Point them at a matching PEM certificate chain and private key.
Make the key file unreadable by other users (for example chmod 600 or chmod 640).
Exit code: 2.
--mint-token requires the 'api' or 'mcp' feature (not compiled in)
--mint-token creates a signed bearer token for the REST API or the HTTP MCP server. This sipnab build has neither the api nor the mcp feature, so it has no token signer.
What to do: Use a sipnab build compiled with the api or mcp feature.
Exit code: 2.
server error: {0}
The REST API server (--api) could not start, or stopped with an error.
{0} says why:
sipnab could not bind the address;
the command gave only one of --api-tls-cert and --api-tls-key;
a TLS file is unusable;
the bind is not loopback, and no --api-key or --api-signing-key exists;
sipnab could not set up the listener.
At startup this stops the run before the TUI or capture begins.
After startup, sipnab logs the error as API server error: followed by the reason. The API stops serving.
What to do: Act on the reason in {0}:
free or change the --api port;
give both TLS files;
bind 127.0.0.1;
or, for a bind that is not loopback, configure --api-key (SIPNAB_API_KEY) or --api-signing-key (SIPNAB_API_SIGNING_KEY).
Exit code: 2 at startup. None for an error after startup: sipnab logs it, and the run continues.
{name} server error: {e}
A server running beside the capture stopped with an error. {name} is API, MCP stdio or MCP HTTP, and {e} is the error. The other servers and the capture keep running.
What to do: Read {e} for the cause. sipnab does not restart the server during the run, so restart sipnab after you correct the cause.
Exit code: None. sipnab logs the error, and the run continues.
{}: these opt-ins act on the sipnab process or the relay, and with the TUI up the operator at the terminal owns both. Add -N to serve MCP headless with them, or remove them to query this capture beside the TUI
The listed options let an MCP (Model Context Protocol) client act on the sipnab process or on the media relay. They come from --mcp-allow-shutdown, --mcp-allow-open-capture, --mcp-allow-tls-capture, --mcp-allow-save-findings and --mcp-allow-relay-query.
You gave them on a run that serves MCP over HTTP while the interactive terminal interface (TUI) is running.
sipnab refuses them there.
What to do: Do one of these:
Add -N to serve MCP without the TUI, and keep the options.
Remove the listed options to query the capture while the TUI runs.
Exit code: 2.
token TTL must be positive, got {ttl}
--mint-token takes the token lifetime from one of two flags:
from --api-token-ttl when the configuration has a REST API signing key;
otherwise from --mcp-token-ttl.
That value is 0 or negative. {ttl} is the value in seconds. Both flags default to 3600.
What to do: Give a positive number of seconds to the flag that applies, for example --api-token-ttl 3600.
Exit code: 2.
{flag} '{path}': {e}
sipnab could not read the signing-key file. {flag} is --api-signing-key-file or --mcp-signing-key-file, {path} is the file, and {e} is the operating system’s reason.
What to do: Check the path, and check that the user sipnab runs as can read the file.
Exit code: 2.
Media relays (rtpengine and rtpproxy)
{} answered {other:?}, not statistics
A --relay-stats-interval poll got a reply that was not a statistics answer. The first {} is rtpengine at <addr>, and {other:?} is the decoded reply. The poll keeps running on its interval.
What to do: Check that --rtpengine-control points at the relay’s control port.
Exit code: None. sipnab logs the error, and the run continues.
could not start the relay statistics poller ({e}); nothing polled
sipnab could not create the thread that polls relay statistics for --relay-stats-interval. {e} is the operating system’s error from thread creation. No polling happens, and the rest of the run continues.
What to do: Act on the error text, then run again.
Exit code: None. This is a warning, and the run continues.
could not start the rtpengine reconciler ({e}); streams the signaling does not explain will stay unattributed
With --rtpengine-control on a live source, sipnab starts a background thread. The thread asks the relay about RTP streams the SIP signaling does not explain.
sipnab could not create that thread.
{e} is the error.
The capture continues. Such streams stay without a call attribution.
What to do: Act on the error text, then run again.
Exit code: None. This is a warning, and the run continues.
{} did not answer the polled statistics request ({e})
A --relay-stats-interval poll failed. The first {} is rtpengine at <addr>, and {e} is the error. The request times out after 2 seconds. The poll keeps running on its interval.
What to do: Check that the relay is running. Check that --rtpengine-control names its control port, and that this host can reach that port.
Exit code: None. sipnab logs the error, and the run continues.
relay at {addr} answered {other:?}, not per-call statistics
For --relay-compare, sipnab asked the relay at {addr} for the statistics of one call and received a reply of another kind. {other:?} is that reply in sipnab’s internal debug form. sipnab compared nothing.
What to do: Check that --rtpengine-control points at the relay’s ng control port and that the relay is rtpengine.
Exit code: None. sipnab logs the error, and the run continues.
relay at {addr} answered {other:?}, not statistics
For --relay-stats, --relay-stats-call or --relay-stats-list, sipnab asked the relay at {addr} for statistics and received a reply of another kind. {other:?} is that reply in sipnab’s internal debug form. sipnab printed nothing.
What to do: Check that --rtpengine-control points at the relay’s ng control port and that the relay is rtpengine.
Exit code: None. sipnab logs the error, and the run continues.
relay at {addr} did not answer the per-call statistics request for call {call_id} ({e}); sipnab measured {measured} RTP packet(s), but the relay's side did not arrive.
The relay at {addr} did not answer the per-call statistics request for call {call_id}. {e} is the error, and {measured} is sipnab’s own RTP packet count. The run continues.
What to do: Check the --rtpengine-control address, and check that the relay is reachable.
Exit code: None. sipnab logs the error, and the run continues.
relay at {addr} did not answer the statistics request ({e}); asked, nothing came back.
The relay at {addr} did not answer the --relay-stats request. {e} is the error. Over UDP, a timeout cannot tell a stopped relay from a filtered port or a lost reply. The run continues.
What to do: Check the --rtpengine-control address and port, and check that the relay is running and reachable.
Exit code: None. sipnab logs the error, and the run continues.
relay at {addr} refused the per-call statistics request for call {call_id}: {reason}; nothing to compare.
For --relay-compare, the relay at {addr} answered the per-call statistics request for {call_id} with an error. {reason} is the relay’s own reason, for example an unknown Call-ID. sipnab compared nothing.
What to do: Check the Call-ID given to --relay-compare and that the call is still active on that relay.
Exit code: None. sipnab logs the error, and the run continues.
relay at {} refused the statistics request for call {call_id}: {reason}
For --relay-stats-call <CALL-ID>, the relay ({} is its address) answered the statistics request for {call_id} with an error. {reason} is the relay’s own reason, for example an unknown Call-ID.
What to do: Check the Call-ID and that the call is active on that relay. --relay-stats without a Call-ID asks for the relay-wide statistics.
Exit code: None. sipnab logs the error, and the run continues.
relay at {addr} reported {digits} RTP packet(s) for call {call_id}, a value too large to compare; the answer is suspect, carried as received and not truncated.
For --relay-compare, the relay at {addr} reported an RTP packet count for call {call_id} that does not fit in a 64-bit number. {digits} is the value as received. sipnab treats the answer as suspect and does not compare it or shorten it.
What to do: No sipnab setting changes this, because the value comes from the relay. Check the relay’s own statistics for that call.
Exit code: None. sipnab logs the error, and the run continues.
relay at {addr}: {e}; the reply for call {call_id} was discarded and not read (suspect). sipnab measured {measured} RTP packet(s).
The relay at {addr} answered the --relay-compare request for call {call_id} with a reply sipnab could not trust, so sipnab discarded it. {measured} is sipnab’s own RTP packet count for the call. The run continues.
What to do: Retry, and check that nothing else uses the same control channel.
Exit code: None. sipnab logs the error, and the run continues.
relay at {addr}: {e}; the reply was discarded and not read (suspect).
The relay at {addr} answered --relay-stats with a reply sipnab could not trust (for example a mismatched cookie). So sipnab discarded the reply. The run continues.
What to do: Check that only one client talks to the relay’s control port with this address, then retry.
Exit code: None. sipnab logs the error, and the run continues.
--relay-compare needs a relay to ask. Name one with --rtpengine-control <addr>.
--relay-compare <CALL-ID> asks the media relay (rtpengine) for its RTP packet count for one call. But the command line has no relay address in --rtpengine-control. So sipnab asked nothing.
What to do: Add --rtpengine-control <ip:port> with the relay’s ng control port, for example --rtpengine-control 127.0.0.1:22222.
Exit code: None. sipnab logs the error, and the run continues.
--relay-compare will not ask a relay on a run that reads a file: asking transmits. Compare from a live capture (-d <device>).
Asking the relay sends a packet. sipnab does not transmit during a run without a live network source. So --relay-compare asked nothing.
What to do: Run the comparison during a live capture, for example with -d <device>.
Exit code: None. sipnab logs the error, and the run continues.
--relay-stats-interval needs a relay to poll. Name one with --rtpengine-control <addr>.
--relay-stats-interval asks sipnab to poll a media relay’s statistics every N seconds, but the command names no relay, so sipnab polls nothing. The rest of the run continues.
What to do: Add --rtpengine-control <addr:port> with the relay’s control port (for example 127.0.0.1:22222), or remove --relay-stats-interval.
Exit code: None. sipnab logs the error, and the run continues.
--relay-stats-interval will not poll a relay on a run that reads a file: polling transmits. Poll from a live capture (-d <device>).
Polling a relay sends packets, and sipnab transmits only on a run that watches a live source. This run’s source does not permit transmitting, so sipnab polls nothing, and the rest of the run continues. A live interface and a HEP listener permit transmitting. Capture files and uprobe reads do not.
What to do: Do one of these:
Run the poll from a live capture (-d <device>) or a HEP listener (--hep-listen).
Remove --relay-stats-interval from runs that read files.
Exit code: None. sipnab logs the error, and the run continues.
--relay-stats needs a relay to ask. Name one with --rtpengine-control <addr>, for example --rtpengine-control 127.0.0.1:22222.
--relay-stats, --relay-stats-call or --relay-stats-list asks the media relay (rtpengine) for its own statistics. But the command line has no relay address in --rtpengine-control. So sipnab asked nothing.
What to do: Add --rtpengine-control <ip:port>, for example --rtpengine-control 127.0.0.1:22222.
Exit code: None. sipnab logs the error, and the run continues.
--relay-stats will not ask a relay on a run that reads a file: asking transmits, and a file's addresses are historical and belong to third parties. Ask from a live capture (-d <device>).
Asking the relay sends a packet. sipnab does not transmit during a run without a live network source.
So the relay statistics request (--relay-stats, --relay-stats-call or --relay-stats-list) asked nothing.
The addresses in a capture file are historical, and belong to other parties.
What to do: Ask from a live capture, for example -d <device>.
Exit code: None. sipnab logs the error, and the run continues.
--rtpengine-control {addr} asks a live relay which calls are up right now, but this run is reading a capture FILE — offline analysis never transmits. The calls in a file ended in the past; the relay's answer would describe whatever is up TODAY, which is other people's traffic. Passive decoding of any relay control plane already in the capture still runs; capture live with -d <device> to ask.
A warning: --rtpengine-control {addr} asks a live relay which calls are active now. This run has no live network source, so sipnab does not ask.
The calls in a capture file ended in the past.
The relay’s answer would describe current calls.
sipnab still decodes any relay control traffic present in the capture.
What to do: Capture live with -d <device> to have sipnab ask the relay, or remove --rtpengine-control from file runs.
Exit code: None. This is a warning, and the run continues.
--rtpengine-control {addr} is not an address and port ({e}).
The --rtpengine-control value {addr} is not an IP address and port, so --relay-compare asked nothing. {e} is the parse error. sipnab accepts only a numeric IP:port form and does not resolve host names.
What to do: Give the relay’s ng control address as IP:port, for example --rtpengine-control 127.0.0.1:22222.
Exit code: None. sipnab logs the error, and the run continues.
--rtpengine-control {addr} is not an address and port ({e}). It names the relay's ng control port, for example 127.0.0.1:22222. Nothing was asked, so streams this relay handles stay unattributed.
At startup sipnab asks the relay named by --rtpengine-control which calls are active. It does this to attribute media streams to calls.
The value {addr} is not an IP address and port. {e} is the parse error.
So sipnab asked nothing, and streams that relay handles stay unattributed.
The capture still runs.
What to do: Give the relay’s ng control port as numeric IP:port, for example --rtpengine-control 127.0.0.1:22222.
Exit code: None. sipnab logs the error, and the run continues.
--rtpengine-control {addr} is not an address and port ({e}); nothing is polled.
The value of --rtpengine-control must be a literal IP address and port, such as 127.0.0.1:22222. sipnab does not resolve host names. {addr} is the value as typed, and {e} is the parse error. Because the value did not parse, the statistics poller does not start. The rest of the run continues.
What to do: Give --rtpengine-control an IP address and port, for example --rtpengine-control 127.0.0.1:22222, using the relay’s control (ng) port. An IPv6 address needs brackets, for example [::1]:22222.
Exit code: None. sipnab logs the error, and the run continues.
--rtpengine-control {addr} is not an address and port ({e}); nothing was asked.
The --rtpengine-control value {addr} is not an IP address and port, so the relay statistics request (--relay-stats, --relay-stats-call or --relay-stats-list) asked nothing. {e} is the parse error.
What to do: Give the address as numeric IP:port, for example --rtpengine-control 127.0.0.1:22222.
Exit code: None. sipnab logs the error, and the run continues.
{}: {} stepped backwards {} -> {} between polls; a cumulative counter cannot decrease, so the relay probably restarted (suspect). The counters below are since an unknown start.
Between two --relay-stats-interval polls, a numeric counter that the relay reports went down.
The first {} is rtpengine at <addr>.
The second is the counter name.
The last two are the previous and current values.
Cumulative counters only increase. So sipnab marks the reading as suspect:
the relay may have restarted;
the counters that follow count from an unknown start.
What to do: Check whether the relay restarted at that time. Compare later readings with each other, not with readings before this line.
Exit code: None. This is a warning, and the run continues.
the relay statistics poll thread panicked
The background thread that polls the relay for statistics stopped with an internal error (a panic). The rest of the run continues, and relay statistics from that thread are incomplete.
What to do: Report it as a sipnab issue, with the command line you used.
Exit code: None. This is a warning, and the run continues.
the rtpengine reconciler thread panicked
When the TUI closed, sipnab found that the rtpengine reconciler thread had ended with a panic (an internal failure). That thread matches the media relay’s view of calls with the sipnab view.
Release builds use panic = "abort". That ends the whole process at the panic.
So this line appears only in builds that unwind on panic.
What to do: This is an internal failure in sipnab, not a setting. Report it with the command line you used and the log output.
Exit code: None. sipnab logs this warning during shutdown.
{}: this poll's round trip took {elapsed:.1?}, longer than the {}s interval; the polling cadence has slipped and is slower than requested.
One relay statistics poll took longer than the --relay-stats-interval. The first {} is rtpengine at <addr>, {elapsed:.1?} is the round-trip time, and the second {} is the interval in seconds. Polls never overlap, so the next poll starts later, and readings arrive less often than you requested.
What to do: Increase --relay-stats-interval above the round-trip time shown, or check why the relay is slow to answer.
Exit code: None. This is a warning, and the run continues.
TLS decryption and uprobes
A keylog producer only records keys for what it attached to. Check both halves of that: the TLS library — eCapture picks one by looking at curl, which need not be the one the SIP daemon maps, so pass --libssl with the path the daemon shows in /proc/<daemon-pid>/maps — and the process, since --pid pins it to a single worker while a forking daemon spreads connections across all of them. Give sipnab --keylog-watch so keys minted after it starts are read too.
Explains why a key-log producer such as eCapture may have recorded no keys: it may have attached to a different TLS library or to a different process.
What to do:
Pass the key-log producer the library that the SIP daemon maps (shown in /proc/<daemon-pid>/maps).
Cover every worker process.
Give sipnab --keylog-watch.
Exit code: None. This is a warning, and the run continues.
Cannot open keylog FIFO {}: {e}
The --keylog path is a FIFO (named pipe), and sipnab could not open it for reading. {} is the path and {e} the operating system error (for example permission denied or no such file). The run continues without TLS secrets from that pipe.
What to do: Check that the FIFO exists and that the user starting sipnab can read it. sipnab opens it before dropping privileges, so the starting user’s permissions apply.
Exit code: None. sipnab logs the error, and the run continues.
Capture the handshake: restart the connection while the capture is running, or capture continuously from before the connections you want to read.
The remedy for a capture that missed the TLS handshake.
What to do: Restart the connection while the capture runs, or capture continuously from before the connections start.
Exit code: None. This is a warning, and the run continues.
Failed to load --dtls-keylog {keylog}: {e:#}
In the TUI, sipnab could not load the key log named by --dtls-keylog.
That file supplies keys for decrypting DTLS-SRTP media. DTLS-SRTP encrypts RTP, and its keys come from a DTLS handshake.
{keylog} is the path.
{e:#} is the reason with its causes. When sipnab could not read the file, it is Loading DTLS keylog from, followed by the path and the operating system’s reason. Examples of the reason are No such file or directory or Permission denied.
The TUI keeps running without DTLS-SRTP decryption.
A headless run (-N) prints the same text and exits 1.
What to do: Correct the path or the file permissions, or point --dtls-keylog at an NSS key log file (the SSLKEYLOGFILE format).
Exit code: None in the TUI, where the run continues without DTLS-SRTP decryption. 1 in a headless run.
Failed to load --keylog {}: {e:#}
sipnab could not read the TLS key log file named by --keylog.
{} is that path.
{e:#} is the reason with its full chain of causes. It includes the operating-system error, or the parse error for the file.
A run that asked for decryption stops instead of continuing without it.
What to do: Check these:
the path is correct;
the file exists, and the user sipnab runs as can read it;
its lines are in NSS SSLKEYLOGFILE format.
Exit code: 1.
Failed to load --srtp-keys {keyfile}: {e:#}
In the TUI, sipnab could not load the SRTP master-key file named by --srtp-keys.
{keyfile} is the path.
{e:#} is the reason with its causes. When sipnab could not read the file, it is Failed to read SRTP key file:, followed by the path and the operating system’s reason. Examples of the reason are No such file or directory or Permission denied.
The TUI keeps running with no SRTP decryption context.
A headless run (-N) prints the same text and exits 1.
What to do: Correct the path or the file permissions, or fix the file’s contents so that sipnab accepts each key line. Without --srtp-keys, sipnab still decrypts with SDES keys it reads from SDP a=crypto lines.
Exit code: None in the TUI, where the run continues without SRTP decryption. 1 in a headless run.
Failed to load --tls-key {keyfile}: {e:#}
sipnab could not load the RSA private key named by --tls-key. sipnab uses it to decrypt TLS 1.2 connections that use RSA key exchange.
{keyfile} is the path.
{e:#} is the reason with its causes. It is one of these:
when sipnab could not read the file: reading TLS private key from, followed by the path and the operating system’s reason. Examples of the reason are No such file or directory or Permission denied;
a statement that the file is not a PKCS#1 or PKCS#8 PEM RSA private key.
What to do: Check these:
the path is correct, and readable by the user sipnab runs as;
the file is an RSA private key in PEM format. That is the text format whose first line names RSA PRIVATE KEY or PRIVATE KEY.
Exit code: 1.
--hep-tls-ca verifies the collector's certificate and does nothing without --hep-send-transport tls
--hep-tls-ca names the certificate authority that sipnab uses to check the certificate of the HEP collector that --hep-send forwards to. HEP (Homer Encapsulation Protocol) is the format sipnab uses to forward captured packets. That check happens only on a TLS connection, and you did not set --hep-send-transport to tls (it defaults to UDP).
What to do: Add --hep-send-transport tls to forward over TLS, or remove --hep-tls-ca.
Exit code: 2.
--hep-tls-cert/--hep-tls-key are what a TLS listener presents and do nothing without --hep-listen-transport tls
--hep-tls-cert and --hep-tls-key are the certificate and private key that the HEP listener (--hep-listen) presents to senders over TLS.
You gave at least one of them.
But you did not set --hep-listen-transport to tls. It defaults to UDP.
So sipnab would use neither.
What to do: Add --hep-listen-transport tls to accept HEP over TLS, or remove --hep-tls-cert and --hep-tls-key.
Exit code: 2.
--hep-tls-extra-ca adds to the roots the collector's certificate is verified against and does nothing without --hep-send-transport tls
--hep-tls-extra-ca adds certificate authorities (roots) to a set. sipnab uses that set to check the certificate of the HEP collector that --hep-send forwards to.
That check happens only on a TLS connection.
You did not set --hep-send-transport to tls. It defaults to UDP.
What to do: Add --hep-send-transport tls to forward over TLS, or remove --hep-tls-extra-ca.
Exit code: 2.
--keylog and --keylog-fd name different sources of the same secrets; pass one, not both
--keylog reads TLS session secrets from a path. The secrets are a key log file in NSS SSLKEYLOGFILE format.
--keylog-fd reads the same kind of secrets from an already-open file descriptor.
You gave both. sipnab does not choose between them.
What to do: Keep one of the two flags and remove the other.
Exit code: 2.
--keylog-fd {fd} is not a readable descriptor: {e}
sipnab could not duplicate the file descriptor number given to --keylog-fd.
{fd} is that number.
{e} is the operating system error. For example, a bad file descriptor when that number is not open in sipnab’s process.
The run continues without this keylog stream. So no TLS secrets arrive from it.
What to do:
Start sipnab from a process that passes the descriptor open to it (not closed on exec).
Give --keylog-fd the number of that descriptor.
Alternatively, name a keylog file or FIFO with --keylog.
Exit code: None. sipnab logs the error, and the run continues.
--keylog-fd must be a descriptor sipnab inherited, got {fd}
--keylog-fd takes the number of a file descriptor (an open file handle) that the program starting sipnab left open for it. {fd} is the value you gave, which is negative, and no descriptor number is negative. This check refuses negative numbers only.
What to do: Pass the non-negative number of the descriptor that the starting program opened for sipnab, for example --keylog-fd 3. The command line accepts a negative value only in the form --keylog-fd=-1, because the parser reads a bare -1 as a flag.
Exit code: 2.
--keylog-fd requires the 'tls' feature (not compiled in)
--keylog-fd names an already-open file descriptor from which sipnab reads TLS key log lines (the secrets that let it decrypt TLS traffic). This sipnab build does not include TLS decryption support (the tls feature), so it cannot use the descriptor.
What to do: Use a sipnab build that includes the tls feature, or remove --keylog-fd.
Exit code: 2.
Keylog stream read failed: {e}
The TLS key log can be a stream:
--keylog-watch;
--keylog-fd;
or a key log that sipnab opened in the privileged startup window, such as a FIFO.
Then sipnab reads what the stream already holds before the first packet. That first read failed. {e} is the error. The run continues, and later polls of the same source still run.
What to do: Check that the user sipnab runs as can read the key log path or descriptor. Check that the producer is writing to it.
Exit code: None. This is a warning, and the run continues.
Key material is NOT locked into RAM: {reason}
A warning: the run loads decryption keys, and sipnab could not lock its memory into RAM. So the operating system may write key material to swap.
{reason} gives the cause.
On Linux, mlockall failed. Usually the memory-lock limit RLIMIT_MEMLOCK is too low.
On other systems, the reason says that sipnab locks memory on Linux only.
The run continues.
What to do: Raise the memory-lock limit, with ulimit -l or LimitMEMLOCK= in the systemd unit, as the reason states.
Exit code: None. This is a warning, and the run continues.
manual SRTP keys loaded from {keyfile} — use only in test environments
--srtp-keys <file> loaded SRTP (encrypted RTP) keys from a file you supplied by hand. {keyfile} is that path. sipnab prints this warning on every such run, including at -q, because manually supplied key material is a testing aid.
What to do: If you intend this, you need to do nothing. On production traffic, omit --srtp-keys. sipnab still picks up keys from SDP a=crypto lines without it.
Exit code: None. This is a warning, and the run continues.
\n{unreachable} of these cannot be reached from sipnab's mount namespace and would NOT be captured. They are most likely inside containers; run as root.
A warning after the --uprobe-list table: sipnab cannot open {unreachable} of the listed libraries at a path whose file matches the mapped library.
sipnab compares the inode, through /proc/<pid>/root and then the plain path.
The table marks them (UNREACHABLE), and sipnab would not probe them.
Libraries inside containers are the usual case.
What to do: Run sipnab as root so it can reach the libraries through /proc/<pid>/root.
Exit code: 0. This is a warning, and sipnab still prints the listing.
No TLS library is mapped by any process sipnab can see.\nEither nothing here uses OpenSSL or wolfSSL, or sipnab cannot read\n/proc/<pid>/maps — try again as root.
--uprobe-list found no process mapping a TLS library sipnab can probe (OpenSSL or wolfSSL). It reads /proc/<pid>/maps for each process, and it does not see a process whose map it cannot read. When the command line includes --uprobe-flavor, sipnab counts only libraries of the named flavors.
What to do:
Run sipnab --uprobe-list as root, so that every process’s map is readable.
Check that the program you want to observe is running, and uses OpenSSL or wolfSSL.
Remove --uprobe-flavor to count both flavors.
Exit code: 1.
Or skip the external extractor: `sudo sipnab --uprobe-list` reports what each process maps, and `sudo sipnab -N --uprobe-tls` probes every mapped TLS library itself, with no --libssl to choose and no keylog.
Printed with the list of mapped libraries. sipnab can read the TLS traffic itself with uprobes (probes that sipnab attaches to functions in the TLS library).
What to do: Run sudo sipnab --uprobe-list to see what each process maps, or run sudo sipnab -N --uprobe-tls.
Exit code: None. This is a warning, and the run continues.
--pcap-export-mode decrypted requires the 'tls' feature (not compiled in): use raw for original packets without keys
--pcap-export-mode decrypted writes TLS traffic after decryption, which needs the tls Cargo feature (a build-time option). This sipnab binary does not include that feature. raw writes the original packets as captured.
What to do: Use --pcap-export-mode raw, or use a sipnab binary built with the tls feature (--features tls or --features full).
Exit code: 2.
Restart the connection while the capture is running — bounce the far end, or the daemon — so the stream is captured from its first record.
The remedy for a capture that joined connections already running.
What to do: Restart the connection (bounce the far end, or the daemon) while the capture runs.
Exit code: None. This is a warning, and the run continues.
sipnab could not decrypt {unread} TLS application-data record(s): it holds no key material for any session in this capture, so this run says nothing about what that traffic contained.
sipnab holds no key material for any TLS session in the capture. So {unread} application-data records went unread. The run says nothing about their contents.
What to do: Read the lines that follow.
Exit code: None. This is a warning, and the run continues.
sipnab discarded {} TLS record(s) held from before a key arrived: the late-decrypt hold is bounded ({} MiB total, {} record(s) per direction, {}s), and it filled before any key matched them. Start the key source before the capture, or expect the first message of a call to be missing.
sipnab holds TLS records that arrive before their key, so that it can decrypt them later, and that hold filled up. The first number is how many records sipnab discarded. The others are the hold’s limits: total MiB, records per direction, and seconds.
What to do: Start the key source before the capture, or expect the first message of a call to be missing.
Exit code: None. This is a warning, and the run continues.
sipnab holds keys for {} TLS session(s) and could not decrypt any of the {} application-data record(s) it saw.
sipnab holds keys for the first number of TLS sessions and could not decrypt any of the second number of records.
What to do: Read the next two lines.
Exit code: None. This is a warning, and the run continues.
sipnab loaded {} keylog line(s) and built no session from any of them, so the {} TLS application-data record(s) in this capture went unread.
sipnab loaded the first number of key-log lines. It could not build a TLS session from any of them. So the second number of TLS application-data records went unread.
What to do: Read the two lines that follow.
Exit code: None. This is a warning, and the run continues.
The handshake is missing. A TLS 1.2 key log gives the master secret; the server random and cipher suite that expand it into record keys are in the ServerHello, and a capture that started after the connection did never saw one. Nothing later in the capture can supply them.
Follows the line above. For TLS 1.2, the session keys also need the server random value and the cipher suite from the ServerHello message. This capture started after the handshake.
What to do: Capture the handshake, as the next line says.
Exit code: None. This is a warning, and the run continues.
The usual cause is a capture that began against connections which were already running. A TLS record is numbered by a counter both endpoints keep privately, nothing on the wire carries it, and sipnab searches only the first {} records of a stream for it — a trunk that has been up for hours is far past that. Capturing the handshake does not help; the counter depends on how many records have gone by since.
A TLS record’s sequence number is not on the wire. sipnab searches only the first {} records of a stream for it. sipnab therefore cannot decrypt a capture that joined long-running connections.
What to do: Restart the connection while the capture runs, as the next line says.
Exit code: None. This is a warning, and the run continues.
This host maps {}. Pass the one the SIP daemon uses, e.g. `ecapture tls -m keylog -k keys.log --libssl={}`.
Lists the TLS library paths that processes on this host map. The second {} is the first of them, shown in an example eCapture command.
What to do: Pass the library that the SIP daemon uses to the key-log producer.
Exit code: None. This is a warning, and the run continues.
TLS late decrypt: {} record(s) opened only after the capture ended -- their keys arrived too late to place the messages in this run. Re-read the saved capture with the same keylog to see them.
sipnab held some TLS records because their keys had not arrived. At the end of the capture, the late keys opened them.
That came too late for this run’s analysis to include them.
{} is the number of records.
sipnab holds records when the key log can grow during the run (--keylog-watch or --keylog-fd).
What to do: Read the saved capture again with -I <file> and the same --keylog. On that run the keys are present from the start.
Exit code: None. This is a warning, and the run continues.
{} TLS record(s) were still waiting when the run ended: no key ever arrived for them. Nothing was discarded and starting the capture earlier would not have helped -- the key source never produced those secrets.
{} TLS records were still waiting when the run ended, because no key for them ever arrived. sipnab discarded nothing.
What to do: Starting the capture earlier does not help. Check that the key source produces secrets for these connections.
Exit code: None. This is a warning, and the run continues.
--uprobe-list needs Linux kernel uprobes and a sipnab built with the `native` feature
--uprobe-list lists the TLS libraries that sipnab could attach uprobes to. Uprobes are Linux kernel hooks on functions inside a running program’s TLS library. sipnab uses them to read decrypted traffic.
This build runs on a system without Linux uprobes. Or its build did not include the native feature.
What to do: Run a sipnab built with the native feature on Linux.
Exit code: 1.
vCon export, fetch and forwarding
'{url}': a base URL with a query cannot take the read path; give a template holding {{uuid}}
You gave the fetcher a base URL with a ?query, and a store kind that builds the read address by adding a path (vcon-store, conserver, vcon-mcp).
sipnab cannot add a path after a query.
{url} is the URL as sipnab parsed it.
The line starts with --vcon-fetch-url or [vcon_fetch] url.
What to do: Do one of these:
Give the full read URL as a template, with {uuid} where the uuid goes. For example, https://host/api/vcon/{uuid}?x=1.
Remove the query from the base URL.
Exit code: 2 when the URL came from --vcon-fetch-url, and 1 when it came from [vcon_fetch] url.
{AUTH_INLINE} and {AUTH_FLAG} both name the credential; give one
You gave the credential both inline (--vcon-forward-auth or SIPNAB_VCON_FORWARD_AUTH) and as a file (--vcon-forward-auth-file). The forwarder takes one source.
The flag definition declares the two in conflict. So the command-line parser refuses the pair with its own message before this check runs.
What to do: Keep one source. Unset SIPNAB_VCON_FORWARD_AUTH and drop --vcon-forward-auth, or drop --vcon-forward-auth-file.
Exit code: 2.
{AUTH_INLINE} and {AUTH_KEY} both name the credential; give one, or name another file with {AUTH_FLAG}, which replaces the key
You gave the credential inline (--vcon-forward-auth or SIPNAB_VCON_FORWARD_AUTH), and the config file also names a credential file with [vcon_forward] auth_file. The forwarder takes one source.
What to do: Unset SIPNAB_VCON_FORWARD_AUTH and drop --vcon-forward-auth, or remove [vcon_forward] auth_file from the config file. A --vcon-forward-auth-file on the command line replaces the config key.
Exit code: 2.
{url} answered {status} ({})
The store answered with an unexpected HTTP status ({status}). {} is the start of its answer.
What to do: Read the store’s answer and check its logs.
Exit code: 1.
{url} answered {}: the store refused the credential or this client ({}); nothing more is fetched
The store answered 401 or 403: it refused the credential or this client. The first {} is the status, and the second is the start of the store’s answer. sipnab fetches no further uuid.
What to do: Check the credential that you gave with the --vcon-fetch auth settings.
Exit code: 3.
{name}: {method} {url} answered {status}; will retry
The store answered container {name} with a status that the forwarder retries: any 5xx, a 3xx, or a 2xx outside the range that the store kind counts as delivered. {method} is POST or PUT, {url} is where the forwarder sent it, and {status} is the status code.
What to do: For 5xx answers, check the state of the store. For a 3xx answer, set --vcon-forward-url to the address the store redirects to, because the forwarder does not follow redirects.
Exit code: None. This is a warning. The container stays in the spool, and the forwarder retries it with a delay that doubles each time. With --vcon-forward-once, the run exits 1.
'{shown}': a URL cannot hold whitespace
The vCon store URL contains a space, tab, line break or other control character. sipnab refuses it.
A vCon is a JSON container for one conversation. The forwarder sends vCons to a store, and the fetcher reads them back.
The line starts with the setting the URL came from, for example --vcon-forward-url or [vcon_fetch] url.
{shown} is the URL as written, with any user:password@ part replaced by [redacted].
What to do: Remove the whitespace from the URL. Percent-encode a space that belongs in the path or query as %20.
Exit code:
2 when the URL came from a flag (--vcon-forward-url, --vcon-forward-replace-url or --vcon-fetch-url);
1 when it came from the config file ([vcon_forward] url, [vcon_forward] replace_url or [vcon_fetch] url).
'{shown}': a URL sent to a store has no fragment
The vCon store URL contains a #. sipnab refuses any URL with a # in it, because an HTTP client never sends a fragment to a server. The line starts with the setting the URL came from, for example --vcon-forward-url or [vcon_fetch] url. {shown} is the URL as written, with any user:password@ part replaced by [redacted].
What to do: Remove the # and everything after it from the URL. If a # belongs in the path or query, percent-encode it as %23.
Exit code:
2 when the URL came from a flag (--vcon-forward-url, --vcon-forward-replace-url or --vcon-fetch-url);
1 when it came from the config file ([vcon_forward] url, [vcon_forward] replace_url or [vcon_fetch] url).
Call-ID '{call_id}' not found in tracked dialogs, so there is no dialog to export. --report lists the Call-IDs this run holds.
--export-vcon <CALL-ID> asks for one call as a vCon container (a JSON format for a call record). This run tracked no dialog with that exact Call-ID. So sipnab exports nothing.
What to do: Run with --report to list the Call-IDs this run holds, then pass one of them exactly. The match is exact. --markdown shows full Call-IDs in the table.
Exit code: 1.
{} cannot be used with {export} on a live capture. A live run writes each call's container shortly after the call ends, and a run stopped by a signal writes nothing more, so the redaction map and tombstones this run would write at its end are never written. Use {} with -I on a saved capture, which always runs to its end
The flags listed in the first {} write their output when a run ends. They come from --redact, --redact-map and --content-deny-tombstone.
{export} is --export-vcon or --export-vcon-when.
On a live capture (no -I), sipnab writes each vCon container shortly after its call ends.
A live run that a signal stops writes nothing more.
So this run would never write the redaction map and tombstones.
The second {} is it or them.
What to do: Do one of these:
Run the export with -I on a saved capture file. That always runs to its end.
Remove the listed flags from the live run.
Exit code: 2.
cannot create --redact-map '{}': {e}
sipnab could not create the --redact-map file. The text after the path is the operating system’s reason.
What to do: Check that the directory exists and that the user sipnab runs as can write to it.
Exit code: 1.
{name}: cannot read it: {e}; will retry
The forwarder could not read container {name} from the spool, for a reason other than a missing file. {e} is the operating system error. The forwarder opens the file without following a symbolic link.
What to do: Give the sipnab user read permission on the files in the spool.
Exit code: None. This is a warning. The container stays in the spool, and the forwarder retries it with a delay that doubles each time. With --vcon-forward-once, the run exits 1.
cannot read --redact-key-file '{}': {e}
--redact-key-file names a file that sipnab could not read, so sipnab wrote no redacted vCon. The text after the path is the operating system’s reason.
What to do: Check the path, and check that the user sipnab runs as can read the file.
Exit code: 1.
cannot read the spool '{}': {e}
The forwarder could not list the files in its spool directory at the start of a pass, so that pass sends nothing. {} is the spool path, and {e} is the operating system error. The forwarder tries again after --vcon-forward-interval.
What to do: Give the sipnab user read and execute permission on the spool directory, and check that it still exists.
Exit code: None. This is a warning, and the run continues. With --vcon-forward-once, the run exits 0.
Could not create the vCon directory '{}': {e}. Nothing was exported.
sipnab could not create the directory named by --export-vcon-dir. The quoted path is that directory, and the text after it is the operating system’s reason. sipnab wrote no vCon file.
What to do: Check that the parent directory exists, and that the user sipnab runs as can write to it. Or name a different directory.
Exit code: 1.
{name}: could not move it to '{}': {e}
After the store’s answer, the forwarder could not rename container {name} into the delivered or failed directory. {} is that directory, and {e} is the operating system error. The container stays in the spool, and the forwarder sends it again on the next pass.
What to do: Give the sipnab user write permission on the spool and on the directory the message names (--vcon-forward-done or --vcon-forward-failed).
Exit code: None. sipnab logs the error, and the run continues. With --vcon-forward-once, the run exits 1.
{name}: could not return the rewritten container to the spool: {e}
Something rewrote container {name} in the spool while the forwarder was sending it.
The forwarder had already moved the file into the delivered or failed directory.
It found that the file was the newer version, which the store has not received.
Linking it back into the spool failed.
{e} is the operating system error.
The newer version stays in the delivered or failed directory. The forwarder does not send it.
What to do:
Move {name} from the delivered or failed directory back into the spool, so that the forwarder sends it.
Give the sipnab user write permission on the spool.
Exit code: None. sipnab logs the error, and the run continues. With --vcon-forward-once, the run exits 1.
{name}: could not write {record_name}: {e}
The forwarder moved container {name} to the failed directory. But it could not write its failure record {record_name}.
The record is <name>.error.json. It holds the store’s answer or the reason.
{e} is the operating system error.
What to do: Give the sipnab user write permission on the failed directory, and check that the filesystem has free space.
Exit code: None. sipnab logs the error, and the run continues. With --vcon-forward-once, the run exits 1.
Could not write '{}': {e}. {written} container(s) were written before this.
sipnab could not write the vCon file at the quoted path.
The text after the path is the operating system’s reason.
{written} is how many vCon files this run had already written before it stopped.
What to do: Check free space and write permission in the --export-vcon-dir directory, then run the export again.
Exit code: 1.
Could not write the vCon for Call-ID '{call_id}' to '{}': {e}. Nothing was exported.
sipnab built the vCon container for {call_id} but could not write it to the --vcon-out path '{}'. {e} is the operating system’s error. sipnab writes the file atomically (it renames a temporary file into place), so a file already at that path stays unchanged.
What to do: Check that the directory of the --vcon-out path exists, and that the user sipnab runs as can write to it. Or choose another path.
Without --vcon-out, sipnab writes the container to standard output.
Exit code: 1.
{uuid}: {} exists; not fetched. --vcon-fetch-overwrite replaces it
--vcon-fetch did not fetch {uuid} because the output file (the {}) already exists.
What to do: Pass --vcon-fetch-overwrite to replace it, or move the file.
Exit code: 1.
--export-vcon-when is not a valid filter expression: {e}
sipnab could not parse the expression given to --export-vcon-when. It uses the same filter language and alias expansion as --filter, and sipnab parses it before the capture opens. {e} is the parser’s reason.
What to do: Correct the expression so that it is valid --filter syntax. An expression that works with --filter works here.
Exit code: 2.
--export-vcon-when needs --export-vcon-dir. Nothing was exported.
A run that selects calls with --export-vcon-when also needs --export-vcon-dir to name the directory for the vCon files. You did not give it, so sipnab wrote no vCon file.
What to do: Add --export-vcon-dir <DIR> to the command.
Exit code: 1.
gives `{name}` a value holding a control character
The credential line names header {name}, but its value contains a control character. For example, a tab or a carriage return inside the value. An HTTP header cannot carry one.
sipnab does not print the value.
The line starts with the source: --vcon-forward-auth (or SIPNAB_VCON_FORWARD_AUTH), or the auth file setting and path.
The forwarder and the fetcher read one header line, Header-Name: value.
When --vcon-forward-kind or --vcon-fetch-kind is vcon-store, conserver or vcon-mcp, sipnab uses a line that fails this check as a bare key instead.
You therefore see this refusal only with the generic kind (the default).
What to do: Rewrite the credential as one line, Header-Name: value, with no control characters in the value.
Exit code: 2 when the credential came from --vcon-forward-auth, SIPNAB_VCON_FORWARD_AUTH, --vcon-forward-auth-file or --vcon-fetch-auth-file, and 1 when [vcon_forward] auth_file or [vcon_fetch] auth_file named the file.
gives `{name}` no value
The credential line names header {name}, but has nothing after the colon.
The line starts with the source: --vcon-forward-auth (or SIPNAB_VCON_FORWARD_AUTH), or the auth file setting and path.
The forwarder and the fetcher read one header line, Header-Name: value.
When --vcon-forward-kind or --vcon-fetch-kind is vcon-store, conserver or vcon-mcp, sipnab uses a line that fails this check as a bare key instead.
You therefore see this refusal only with the generic kind (the default).
What to do: Put the credential after the colon, for example Authorization: Bearer <token>.
Exit code: 2 when the credential came from --vcon-forward-auth, SIPNAB_VCON_FORWARD_AUTH, --vcon-forward-auth-file or --vcon-fetch-auth-file, and 1 when [vcon_forward] auth_file or [vcon_fetch] auth_file named the file.
'{}' has no {{uuid}} to fill in
The forwarder’s replace URL holds no {uuid}.
When the store answers 409, it already holds that uuid. The forwarder then sends the container with PUT to the replace URL, with the container’s uuid filled in.
{} is the template as written, with any user:password@ part replaced by [redacted].
The line starts with --vcon-forward-replace-url or [vcon_forward] replace_url.
What to do: Write {uuid} in the replace URL where the uuid goes, for example https://store.example.com/v1/vcons/{uuid}.
Exit code: 2 when the URL came from --vcon-forward-replace-url, and 1 when it came from [vcon_forward] replace_url.
{flag} is a vCon fetcher setting and needs --vcon-fetch
{flag} is the first option you gave that only the vCon fetcher reads. That is a fetcher option such as --vcon-fetch-url or --vcon-fetch-out.
But you did not give --vcon-fetch. So the fetcher does not run.
vCon is a JSON format for a recorded conversation.
What to do: Add --vcon-fetch UUID to fetch a vCon, or remove the named option.
Exit code: 2.
{flag} is a vCon forwarder setting and needs --vcon-forward
{flag} is the first option you gave that only the vCon forwarder reads. That is a forwarder option such as --vcon-forward-url or --vcon-forward-once.
But you did not give --vcon-forward. So the forwarder does not run.
This check skips --vcon-forward-auth.
vCon is a JSON format for a recorded conversation.
What to do: Add --vcon-forward to run the forwarder, or remove the named option.
Exit code: 2.
{uuid:?} is not a uuid
The value you gave --vcon-fetch is not a uuid, so sipnab requested nothing for it.
What to do: Pass the vCon’s uuid.
Exit code: 1.
{flag} '{}' is on another filesystem from the spool; a move must be a rename
The delivered or failed directory is on a different filesystem from the spool. The forwarder moves a container out of the spool by renaming it, which works only within one filesystem. {flag} is --vcon-forward-done ([vcon_forward] done) or --vcon-forward-failed ([vcon_forward] failed), and {} is the directory.
What to do: Choose a delivered and a failed directory on the spool’s filesystem. Or leave both unset to use delivered and failed inside the spool.
Exit code: 2.
{value} is out of range: give a whole number from {} to {}
A whole-number setting of the vCon forwarder or fetcher is outside its range.
{value} is the number given.
The two {} are the smallest and largest accepted values.
Ranges:
interval 1-3600 and timeout 1-600 seconds for the forwarder;
timeout 1-600 for the fetcher;
1-4294967295 for the back-off, response-head, error-body and size settings.
For a flag (such as --vcon-forward-interval), the argument parser reports the error.
For a key, it reads invalid config value: [vcon_forward] <key>: ... or [vcon_fetch] <key>: ....
What to do: Give a whole number inside the range the message states.
Exit code: 2 for a flag, and 1 for a [vcon_forward] or [vcon_fetch] key.
{endpoint} is plain http to another machine: the auth header and every container cross the network unencrypted. Use https:// for anything but loopback
The store URL {endpoint} uses plain http to a host that is not this machine. So the auth header and every container cross the network unencrypted.
What to do: Use an https:// URL for anything but loopback.
Exit code: None. This is a warning, and the run continues.
{flag} '{}' is the spool itself
The delivered or failed directory is the spool directory itself. {flag} is --vcon-forward-done ([vcon_forward] done) or --vcon-forward-failed ([vcon_forward] failed), and {} is the directory.
What to do: Name a different directory on the spool’s filesystem. Or leave the setting unset to use delivered or failed inside the spool.
Exit code: 2.
{from} '{shown}': larger than {MAX_AUTH_FILE} bytes; it holds one line
The credential file is larger than 8192 bytes. It must hold one line. {from} is the setting that named the file (--vcon-forward-auth-file, [vcon_forward] auth_file, --vcon-fetch-auth-file or [vcon_fetch] auth_file). {shown} is its path, and {MAX_AUTH_FILE} is 8192.
What to do: Reduce the file to the one credential line, Header-Name: value. Or reduce it to the bare key, for a store kind that supplies the header.
Exit code: 2 when a flag named the file (--vcon-forward-auth-file or --vcon-fetch-auth-file), and 1 when [vcon_forward] auth_file or [vcon_fetch] auth_file named it.
line {}: {line:?} is not a uuid (1 to 64 characters, each a letter, a digit or '-')
--vcon-fetch - reads uuids from standard input, one per line, and line {} is not a uuid. {line:?} is that line, quoted. A uuid here is 1 to 64 characters, each a letter, a digit or -. sipnab skips blank lines and lines that start with #. The message starts with --vcon-fetch -: .
What to do: Correct or remove the line the message names, or comment it out with #.
Exit code: 2.
names `{name}`, which the forwarder writes itself; name the header that authenticates
The credential line names header {name}. The forwarder writes this header itself on every request (Host, Content-Type, Content-Length, Transfer-Encoding, Connection, User-Agent or Expect).
The line starts with the source: --vcon-forward-auth (or SIPNAB_VCON_FORWARD_AUTH), or the auth file setting and path.
The forwarder and the fetcher read one header line, Header-Name: value.
When --vcon-forward-kind or --vcon-fetch-kind is vcon-store, conserver or vcon-mcp, sipnab uses a line that fails this check as a bare key instead.
You therefore see this refusal only with the generic kind (the default).
What to do: Name the header the store authenticates with, for example Authorization: Bearer <token>.
Exit code: 2 when the credential came from --vcon-forward-auth, SIPNAB_VCON_FORWARD_AUTH, --vcon-forward-auth-file or --vcon-fetch-auth-file, and 1 when [vcon_forward] auth_file or [vcon_fetch] auth_file named the file.
{url}: {problem}; nothing was written
The store’s answer from {url} was incomplete. {problem} says how. sipnab wrote nothing.
What to do: Retry, and check the store and the network path.
Exit code: 1.
{url}: {e}; nothing was written
sipnab could not take the vCon out of the store’s answer from {url}. {e} is the reason. sipnab wrote nothing.
What to do: Check that the store kind setting matches the store.
Exit code: 1.
{name}: {endpoint} not reached: {e}; will retry
The PUT of container {name} to the replace URL failed before the forwarder could read a status. The forwarder sent the PUT after a 409.
{endpoint} is the filled-in replace URL.
{e} is the reason:
no address;
no connection;
a TLS failure;
an answer the forwarder could not read (closed early, not HTTP, or headers over --vcon-forward-max-response-head).
What to do: Check that the host of the replace URL is reachable and serves HTTP or HTTPS. If {e} names the header limit, raise --vcon-forward-max-response-head.
Exit code: None. This is a warning. The container stays in the spool, and the forwarder retries it with a delay that doubles each time. With --vcon-forward-once, the run exits 1.
{name}: {url} not reached: {e}; will retry
The POST of container {name} to the store failed before the forwarder could read a status.
{url} is the store URL.
{e} is the reason:
the host does not resolve;
no connection within --vcon-forward-timeout;
a TLS failure;
an answer the forwarder could not read (closed early, not HTTP, or headers over --vcon-forward-max-response-head).
What to do:
Check that the store’s host and port are reachable from this machine.
Check that the scheme (http:// or https://) matches the store.
If {e} names the header limit, raise --vcon-forward-max-response-head.
Exit code: None. This is a warning. The container stays in the spool, and the forwarder retries it with a delay that doubles each time. With --vcon-forward-once, the run exits 1.
'{shown}': put credentials in --vcon-forward-auth-file, not in the URL
The vCon store URL holds a user name or password before an @ (https://user:secret@host/...).
sipnab refuses it, so that the credential stays out of logs.
The line starts with the setting the URL came from, for example --vcon-forward-url or [vcon_fetch] url.
{shown} is the URL as written, with any user:password@ part replaced by [redacted].
What to do: Remove the user:password@ part from the URL. For the forwarder, put the credential in the file named by --vcon-forward-auth-file (or [vcon_forward] auth_file), or in SIPNAB_VCON_FORWARD_AUTH. For the fetcher, put it in the file named by --vcon-fetch-auth-file (or [vcon_fetch] auth_file).
Exit code:
2 when the URL came from a flag (--vcon-forward-url, --vcon-forward-replace-url or --vcon-fetch-url);
1 when it came from the config file ([vcon_forward] url, [vcon_forward] replace_url or [vcon_fetch] url).
--redact acts on the vCon exporter, which needs the 'vcon' Cargo feature this build does not carry. Rebuild with --features vcon (or --features full); `sipnab --version` lists the features a binary was built with
--redact changes the content of the vCon containers that sipnab exports. vCon is a JSON format for a recorded conversation. The exporter is part of the vcon Cargo feature (a build-time option), and this binary does not include that feature.
What to do: Use a sipnab binary built with --features vcon or --features full. sipnab --version lists the Cargo features that a binary includes.
Exit code: 2.
--redact-map '{}' already exists and sipnab will not write over it. That file may be the only way back from tokens already sent somewhere
--redact-map names the file where sipnab writes a table. The table maps each redaction token back to the original value.
A file (or link) already exists at that path.
sipnab refuses to replace it. It may be the only way to reverse tokens in containers that an earlier run exported.
'{}' is the path.
With --export-vcon <CALL-ID>, the refusal comes before sipnab writes the container. So sipnab exports nothing.
With --export-vcon-when, sipnab has already written the containers to --export-vcon-dir when the refusal happens.
What to do: Pass --redact-map a path that does not exist yet, or move the existing file elsewhere first.
Exit code: 1.
--redact needs a key and none was supplied, so sipnab drew one from the operating system and could not: {e}. There is no weaker fallback: a guessable key makes every token in the export reversible by anyone holding a phone book. Pass --redact-key-file, or fix the entropy source
You gave --redact without --redact-key-file, so sipnab asked the operating system for a random key, and the request failed. sipnab does not fall back to a weaker key, so it wrote no redacted vCon.
What to do: Pass --redact-key-file with a key file, or fix the operating system’s random-number source.
Exit code: 1.
--redact rewrites an EXPORTED container and this run exports none. Pair it with --export-vcon, --export-vcon-when or a [[vcon.rule]], or drop it — a run that accepted --redact and wrote nothing redacted would read as a redacted capture
--redact acts on the vCon containers that a run exports. This run has none of these:
--export-vcon;
--export-vcon-when;
a [[vcon.rule]] in its config file.
So --redact has nothing to act on. vCon is a JSON format for a recorded conversation.
What to do: Add --export-vcon CALL-ID, --export-vcon-when (with --export-vcon-dir) or a [[vcon.rule]], or remove --redact.
Exit code: 2.
refused {name}: {method} {url} answered {}; moved to '{}' beside {record_name}
The store answered with a 4xx status that a retry does not change. So the forwarder moved the container to the failed directory.
Such a status is any 4xx except 401 and 403, and except 409 when you set a replace URL.
{name} is the container file.
{method} is POST or PUT.
{url} is where the forwarder sent it.
The first {} is the status. The second is the failed directory.
{record_name} is <name>.error.json. It holds the store’s answer with the credential removed.
What to do:
Read <name>.error.json for the store’s reason.
Correct the container or the forwarder settings. For example, --vcon-forward-url, --vcon-forward-kind, or --vcon-forward-replace-url for a 409.
Move the container back into the spool to send it again.
Exit code: None. This is a warning, and the run continues. With --vcon-forward-once, the run exits 1.
refused {name}: not sent: {reason} Moved to '{}' beside {record_name}
The store answered 409 (it already holds this uuid), and you set a replace URL. But the forwarder could not build the PUT request. The forwarder moved the container to the failed directory without sending it.
{name} is the container file.
{reason} says why:
the container is not JSON;
it has no uuid;
its uuid is not 1 to 64 letters, digits or -;
the filled-in replace URL does not parse.
{} is the failed directory.
{record_name} is <name>.error.json. It holds the same reason.
What to do:
Read <name>.error.json in the failed directory.
Correct the container or the replace URL (--vcon-forward-replace-url).
Move the container back into the spool to send it again.
Exit code: None. This is a warning, and the run continues. With --vcon-forward-once, the run exits 1.
the answer is larger than {} bytes (--vcon-fetch-max-size); nothing was written
The store’s answer was larger than the --vcon-fetch-max-size limit ({} bytes), so sipnab wrote nothing.
What to do: If you expect a container that large, raise --vcon-fetch-max-size.
Exit code: 1.
the answer's status line and headers are larger than {max} bytes ({flag})
The store’s answer had a status line and headers larger than the limit. So sipnab stopped reading it.
{max} is the limit in bytes (default 65536).
{flag} is the setting that controls it:
--vcon-forward-max-response-head for the forwarder;
--vcon-fetch-max-response-head for the fetcher.
The forwarder treats this as a failed send, and retries the container.
The fetcher records that uuid as failed.
What to do: Raise the limit with the flag the message names, or with [vcon_forward] max_response_head or [vcon_fetch] max_response_head in the config file.
Exit code: For the forwarder, none, because the forwarder retries the container. With --vcon-forward-once, the run exits 1. For the fetcher, 1.
{url}: the container is not JSON: {e}
The store’s answer from {url} is not JSON. {e} is the parser’s reason.
What to do: Check that {url} is the store’s read URL.
Exit code: 1.
{url}: the container's uuid is {}, not the one asked for; nothing was written
The container that the store returned carries a different uuid ({}, or missing) from the one requested. So sipnab did not write it.
What to do: Report it to the store’s operator.
Exit code: 1.
the first retry delay, {} s from {}, is longer than the longest, {} s from {}; give a first delay no longer than the cap
The vCon forwarder’s first retry delay is longer than its longest retry delay.
The four {} are, in order:
the first delay in seconds, and where it came from;
the longest delay, and where it came from.
A source is one of:
--vcon-forward-backoff-first or --vcon-forward-backoff-cap;
[vcon_forward] backoff_first or [vcon_forward] backoff_cap;
the default (2 for the first delay, 300 for the longest).
When sipnab finds this while it loads the configuration file, the printed line starts with invalid config value: .
What to do: Make the first delay no longer than the longest: lower backoff_first or --vcon-forward-backoff-first, or raise backoff_cap or --vcon-forward-backoff-cap.
Exit code:
1 when both values came from the configuration file or the defaults;
2 when a command-line flag supplied one of them.
The {what} for Call-ID '{}' would not serialize: {e}
sipnab built the vCon for the named Call-ID but could not turn it into JSON. {what} is vCon for a normal container, or withheld-dialog vCon for a tombstone. --content-deny-tombstone writes a tombstone for a call that the --content-deny-header rule withheld. The text after the colon is the reason from the serializer.
What to do: Report the message and the Call-ID as a sipnab issue. No flag changes this.
Exit code: 1.
'{shown}': the forwarder speaks http:// and https:// only
The vCon store URL does not start with http:// or https://, the only two schemes sipnab can send to. The line starts with the setting the URL came from, for example --vcon-forward-url or [vcon_fetch] url. {shown} is the URL as written, with any user:password@ part replaced by [redacted].
What to do: Write the URL with http:// or https:// in front, for example https://store.example.com/v1/vcons.
Exit code:
2 when the URL came from a flag (--vcon-forward-url, --vcon-forward-replace-url or --vcon-fetch-url);
1 when it came from the config file ([vcon_forward] url, [vcon_forward] replace_url or [vcon_fetch] url).
'{url}': the {} kind reads at a URL template; write {{uuid}} where the uuid goes
The fetcher’s store kind is generic (the default, which --vcon-fetch-kind or [vcon_fetch] kind sets). That kind has no built-in read path, and the URL holds no {uuid}. {url} is the URL as parsed, and {} is the kind name. The line starts with --vcon-fetch-url or [vcon_fetch] url.
What to do: Do one of these:
Write {uuid} in the URL where the container’s uuid goes, for example https://host/vcons/{uuid}.
Set --vcon-fetch-kind to vcon-store, conserver or vcon-mcp. These supply the read path.
Exit code: 2 when the URL came from --vcon-fetch-url, and 1 when it came from [vcon_fetch] url.
'{}': the read URL holds no {{uuid}}
The fetcher’s read URL holds no {uuid} when the fetcher starts. {} is the URL.
The settings step (read_url) always produces a URL holding {uuid}. Or it refuses the run with its own message first.
So a command-line run does not reach this check.
What to do: Write {uuid} in --vcon-fetch-url (or [vcon_fetch] url) where the uuid goes, or use a --vcon-fetch-kind that supplies the read path.
Exit code: 2.
{uuid}: the store holds no such vCon (404)
The store answered 404: it holds no vCon with that uuid.
What to do: Check the uuid.
Exit code: 1.
{} {} the 'vcon' Cargo feature, which this build does not carry. Rebuild with --features vcon (or --features full); `sipnab --version` lists the features a binary was built with
This sipnab binary does not include the vcon Cargo feature (a build-time option). That feature contains the vCon exporter. vCon is a JSON format for a recorded conversation.
The first {} lists the vCon flags you gave. They come from --export-vcon, --export-vcon-when, --export-vcon-dir, --vcon-digest and --vcon-max-inline-media.
The second {} is needs or need.
What to do: Use a sipnab binary built with --features vcon or --features full, or remove the listed flags. sipnab --version lists the Cargo features that a binary includes.
Exit code: 2.
The vCon for Call-ID '{call_id}' would not serialize: {e}
sipnab built the vCon container for {call_id} but could not convert it to JSON. {e} is the JSON serializer’s error. sipnab writes nothing for that call.
What to do: The code offers no flag that avoids this condition. Report it with the command line you used.
Exit code: 1.
{flag} '{}': not a directory
The path given to {flag} exists and is not a directory. {flag} is --vcon-fetch-out, where the fetcher writes the containers it fetches, or --vcon-audio-fetch-out, where --vcon-audio-fetch writes the audio. {} is the path.
What to do: Name a directory, or a path that does not exist yet. sipnab creates a missing directory with mode 0700.
Exit code: 2.
--vcon-fetch requires the 'vcon' feature (not compiled in)
--vcon-fetch downloads stored vCons (a JSON container format for conversation records) by UUID. This build does not include the vcon feature, so it has no fetcher.
What to do: Use a sipnab build that includes the vcon feature.
Exit code: 2.
vCon forwarder stopped: {why}
The store answered 401 or 403, which refuses the credential or the client for every container alike, so the forwarder stopped. It sends nothing more, and every container stays in the spool. {why} holds the request, the status, the container name and the start of the store’s answer (at most 200 bytes, credential removed).
What to do: Check the credential (--vcon-forward-auth-file, [vcon_forward] auth_file or SIPNAB_VCON_FORWARD_AUTH) and the header name it uses. If a Cloudflare front answered 403 with error code: 1010, check that nothing in front of sipnab replaces its User-Agent header.
Exit code: 3.
--vcon-forward '{}' is not a directory
The spool path given to --vcon-forward exists and is not a directory. The spool is the --export-vcon-dir directory that the forwarder sends containers from. {} is the path.
What to do: Pass the directory that --export-vcon-dir writes to.
Exit code: 2.
--vcon-forward needs a credential: give {AUTH_FLAG}, {AUTH_KEY} in the config file, or the SIPNAB_VCON_FORWARD_AUTH environment variable
You gave --vcon-forward with no credential for the store from any source. The forwarder sends one authentication header with every request and does not run without it.
What to do: Give --vcon-forward-auth-file FILE, set [vcon_forward] auth_file in the config file, or set the SIPNAB_VCON_FORWARD_AUTH environment variable. The file holds one line, Header-Name: value, or the bare key with a --vcon-forward-kind other than generic. Other users must not be able to read it (chmod 600).
Exit code: 2.
{from} needs --vcon-forward-scitt-url ([vcon_forward] scitt_url): the transparency service the lifecycle statements go to
You gave a SCITT setting, such as --vcon-forward-scitt-issuer or [vcon_forward] scitt_sign_key, without the URL of the transparency service. {from} names the setting. The other SCITT settings do nothing without the URL.
What to do: Give --vcon-forward-scitt-url URL or [vcon_forward] scitt_url, or remove the SCITT settings.
Exit code: 2.
{issuer_from} {issuer:?} is not a URI: give a scheme and more, such as https://pbx.example.com/sipnab, of 1 to {} characters
The issuer of the lifecycle statements is not a URI. {issuer_from} names --vcon-forward-scitt-issuer or [vcon_forward] scitt_issuer, {issuer:?} is the value, and {} is MAX_ISSUER_LEN (8192). A statement carries an X.509 chain, and section 6 of draft-ietf-scitt-architecture-22 then requires iss to be a URI of 1 to 8192 characters.
What to do: Give a URI with a scheme, such as https://pbx.example.com/sipnab or urn:example:pbx-1, with no spaces.
Exit code: 2.
{name}: a lifecycle statement did not register with {}; {record_name} says why
The forwarder delivered the container {name}, and the transparency service at {} did not register one of its lifecycle statements: it refused it, or it did not answer. {record_name} is the <name>.scitt record beside the delivered container, which holds the status and the service’s reason. The delivery stands, and sipnab does not retry the statement.
What to do: Read the record. A 400 names the service’s reason, such as an algorithm its registration policy does not admit. Register the statement again by other means if the record must be complete.
Exit code: None. This is a warning, and the forwarder continues.
--vcon-forward requires the 'vcon' feature (not compiled in)
--vcon-forward delivers a spool directory of vCon files to a store. This build does not include the vcon feature, so it has no forwarder.
What to do: Use a sipnab build that includes the vcon feature.
Exit code: 2.
--vcon-resign requires the 'vcon' feature (not compiled in)
--vcon-resign re-signs a signed vCon for a long-term archive. This build does not include the vcon feature, so it cannot sign.
What to do: Use a sipnab build that includes the vcon feature.
Exit code: 2.
--vcon-resign: {message}
--vcon-resign wrote nothing. {message} is the reason. It is one of these:
--vcon-resign-key: ..., when the new signer’s key or certificate does not read, the key is not RSA or EC P-256, other users can read the key, or the certificate is not the key’s. Exit code 2.
a [vcon_input] or --vcon-signer-ca CA file that does not read. Exit code 2.
'FILE': ..., when sipnab refuses the input: it is not JSON, it is not the signed form, a signature does not verify, the signer checks refuse its outermost signer, or that signer’s certificate is not valid now. Exit code 1.
cannot read 'FILE': ..., or the input is over the 64 MiB limit for one container. Exit code 1.
'OUT' exists; sipnab never replaces it: name a new file, or sipnab cannot create or write the output. Exit code 1.
'{}' is {len} bytes, over the {cap}-byte limit for one container
--vcon-resign names an input over the 64 MiB limit for one vCon container, the limit -I applies too. sipnab reads nothing of it. The message follows --vcon-resign: .
What to do: Check the file is the signed vCon you meant.
Exit code: 1.
--vcon-audio-fetch requires the 'vcon' feature (not compiled in)
--vcon-audio-fetch reads back the audio a vCon names by url. This build does not include the vcon feature, so it cannot read a vCon.
What to do: Use a sipnab build that includes the vcon feature.
Exit code: 2.
--vcon-audio-fetch: {reason}
--vcon-audio-fetch did not write a recording, or any. {reason} is why. sipnab prints one line for each recording it refused, and writes the others. It is one of these:
--vcon-key: ..., a [vcon_input] or --vcon-signer-ca file that does not read, or --vcon-audio-fetch-ca: ... or --vcon-audio-fetch-extra-ca: ... for a CA file that does not load. Exit code 2.
'FILE': ..., when the container does not open: it is not a vCon, a signature does not verify, the key does not decrypt it, or the signer checks refuse its signer. Exit code 1.
'FILE': the vCon has no uuid to name a file by, or 'FILE': no recording in the vCon names a url. Exit code 1.
dialog N: ..., naming the recording’s index in dialog, when sipnab refused that recording. The entries below list the reasons. Exit code 1.
names no mediatype, so sipnab cannot tell what audio it is, or mediatype "..." is not audio sipnab writes (audio/x-wav, audio/ogg).
names no content_hash, so the file cannot be checked, or content_hash does not match the file: the file is not the one the vCon names. sipnab checks the hash before it decrypts the file or writes anything.
the file is a JWE and did not decrypt: ...: the file names no recipient that the key that opened the container decrypts.
a connection, TLS or HTTP refusal from the server that holds the file.
What to do: Act on the reason. A file whose hash does not match is not the one the vCon names: fetch it again from where your storage keeps it, and do not use it.
Exit code: 1 or 2, as listed.
'{}' exists; sipnab never replaces it: name a new directory
--vcon-audio-fetch found a file at the path it writes a recording to, <uuid>-dialog<N>.wav or .ogg in --vcon-audio-fetch-out. {} is the path. sipnab fetches nothing for that recording and keeps the file. The message follows --vcon-audio-fetch: dialog N: .
What to do: Name a new --vcon-audio-fetch-out directory, or move the file away.
Exit code: 1.
has content_hash {expected:?}, and sipnab checks sha512 only
The recording’s content_hash names a hash algorithm other than SHA-512. sipnab checks every file it fetches before it reads it, and checks SHA-512 only, the algorithm draft-ietf-vcon-vcon-core-04 section 2.2 names. sipnab writes nothing for the recording. The message follows --vcon-audio-fetch: dialog N: URL: .
What to do: Check the file with a tool that supports the algorithm the vCon names.
Exit code: 1.
the audio is not {} (it does not start with {:?})
The file the recording names matched its content_hash, and, decrypted when it was a JWE, it is not a WAV file (RIFF) or an Ogg file (OggS) as its mediatype says. sipnab writes nothing for the recording. The message follows --vcon-audio-fetch: dialog N: URL: .
What to do: Check what the vCon’s producer wrote at that URL.
Exit code: 1.
the file is a JWE whose cty is {cty:?}, not the mediatype {mediatype:?}
The file the recording names is a JWE, and the media type in its cty header is not the recording’s mediatype. sipnab does not decrypt it. The message follows --vcon-audio-fetch: dialog N: URL: .
What to do: Check what the vCon’s producer wrote at that URL.
Exit code: 1.
url {url:?} ends in no file name sipnab reads beside the container
With --vcon-audio-fetch-local, sipnab reads the file named by the last segment of the recording’s url from the directory that holds the vCon. That segment is empty, starts with a dot, or holds a character other than ASCII letters, digits, -, _ and ., so it could name a file elsewhere. sipnab reads nothing for the recording.
What to do: Fetch the file from the URL, without --vcon-audio-fetch-local.
Exit code: 1.
url {url:?} is not https://, and draft-ietf-vcon-vcon-core-04 section 2.4.1 says "HTTPS MUST be used for retrieval"; nothing was fetched
The recording’s url is not an https:// URL. sipnab does not connect. A [[vcon.rule]] with audio = "url" refuses an audio_url_base that is not https://, so sipnab writes no such URL itself.
What to do: If the file is beside the container, read it with --vcon-audio-fetch-local. Otherwise fetch it from the URL some other way, and check its SHA-512 against the content_hash.
Exit code: 1.
{url} answered {}
The server that holds a recording’s file answered GET with a status other than 2xx. {} is the status. sipnab writes nothing for the recording. The message follows --vcon-audio-fetch: dialog N: .
What to do: Check the file is at that URL, and that the server serves it without a credential.
Exit code: 1.
{url}: the answer is larger than {} bytes ({max_size_setting})
The file a recording names is larger than the limit. {} is the limit and {max_size_setting} the flag that sets it, --vcon-audio-fetch-max-size. sipnab writes nothing for the recording.
What to do: Raise --vcon-audio-fetch-max-size, if the file is the size you expect for the call.
Exit code: 1.
{url}: {problem}, so the file is not whole
The server that holds a recording’s file closed the connection before it sent the length it declared. {problem} gives the two lengths. sipnab writes nothing for the recording.
What to do: Run the command again. If it recurs, check the server.
Exit code: 1.
--vcon-spool-status requires the 'vcon' feature (not compiled in)
--vcon-spool-status counts the vCon export spool: the containers pending, delivered and failed. This build does not include the vcon feature, so it cannot read the spool.
What to do: Use a sipnab build that includes the vcon feature.
Exit code: 2.
--vcon-spool-status: {e}
--vcon-spool-status could not report on the spool. {e} is the reason. It is one of these:
cannot read '{path}': {e}, when the spool directory, or its delivered/ or failed/ directory, exists but sipnab cannot list it;
the reason sipnab could not write the report as JSON.
A directory that does not exist is not an error: it counts as empty.
What to do: Check the path. Check that the user sipnab runs as can list the spool directory, and the delivered/ and failed/ directories beside it.
Exit code: 1.
cannot read '{path}': {e}
The spool status could not list a directory. {path} is the spool directory, or its delivered/ or failed/ directory, and {e} is the operating system’s reason. The command line prints it after --vcon-spool-status: .
What to do: Check that the user sipnab runs as can list that directory.
Exit code: 1.
{shown} is missing beside the container
The spool status found a container in failed/ with no failure record beside it. {shown} is the record’s file name, the container’s name followed by .error.json. This is not an error message: it is the record_problem value for that container in the status report, and the report continues.
What to do: Read the container itself to find out why the forwarder moved it to failed/. Or run the forwarder again on it.
Exit code: None. It is a field in the report.
{shown} cannot be read: {e}
The spool status found a failure record beside a container in failed/ and could not read it. {shown} is the record’s file name, and {e} is the operating system’s reason. It is the record_problem value for that container in the status report, and the report continues.
What to do: Check that the user sipnab runs as can read the record.
Exit code: None. It is a field in the report.
{shown} is {size} bytes, past the {MAX_RECORD_READ}-byte bound this reads; read the file on the host
The spool status found a failure record larger than it reads. {shown} is the record’s file name, {size} its size, and {MAX_RECORD_READ} the bound, 1048576 bytes. It is the record_problem value for that container in the status report, and the report continues.
What to do: Read the record on the host with a text viewer.
Exit code: None. It is a field in the report.
writing --redact-map '{}': {e}
sipnab created the --redact-map file, but a write to it failed part way. The text after the path is the operating system’s reason.
What to do: Check free space on that filesystem, delete the partial map file, and run the export again.
Exit code: 1.
{uuid}: written to {}, but the schema refuses it ({} finding(s)): {}
sipnab wrote the vCon {uuid} to the named file, but the file fails the vCon schema check. The number of findings and each finding follow. sipnab logs this as a warning, but a container with findings makes the run exit 1.
What to do: Read the findings. The file holds what the store returned.
Exit code: 1.
{url}: {e}
The request to {url} failed before an answer arrived. {e} is the reason (for example a connection or TLS error).
What to do: Check the URL, the network path, and the store’s certificate.
Exit code: 1.
{uuid}: {why}
sipnab did not write the vCon {uuid}. {why} is the reason, one of the --vcon-fetch messages in this section.
What to do: Follow the reason that the message gives.
Exit code: 1, or 3 when the store refused the credential.
{}: {e}
sipnab could not write the fetched vCon to the file named before the colon. {e} is the operating system’s reason.
What to do: Check space and permissions in the --vcon-fetch-out directory.
Exit code: 1.
Calls were still waiting for [[vcon.enrich]] after an hour; their containers are not written.
A live capture ended on its own (--duration) while calls still waited for an [[vcon.enrich]] service. An hour passed without them finishing.
Its timeout_secs bounds each service call.
So this means a service kept every call waiting its full timeout.
What to do:
Check the service the earlier [[vcon.enrich]] '...' lines name.
Lower its timeout_secs.
Re-export the calls from a saved capture with -I.
Exit code: None. This is a warning, and the run ends.
{label}[[vcon.enrich]] '{}' for Call-ID '{call_id}': {}: {}. The container is written without its analysis and records this.
Then come the outcome (failed, timeout, malformed or queue-full) and what happened.
sipnab writes the call’s container without that service’s analysis.
Its sipnab-enrichment attachment records the same outcome.
What to do: Read the detail: failed is the service’s HTTP status or exit status, timeout its timeout_secs, malformed an answer that is not an analysis list. queue-full means 64 calls were waiting. The service is slower than the calls arrive.
Exit code: None. This is a warning, and the run continues.
{label}Could not write '{}' after enrichment: {e}
On a live capture, sipnab enriched a call’s container and then could not write it to its spool. {label} names the rule, {} the path and {e} the operating-system error.
What to do: Check the spool directory’s free space and permissions.
Exit code: None. This is a warning, and the run continues.
answered HTTP {status}: {excerpt}
The detail an [[vcon.enrich]] records when its URL answered with a status other than 2xx. {status} is the status and {excerpt} the start of the answer. It appears in the [[vcon.enrich]] '...' for Call-ID line and in the container’s sipnab-enrichment attachment.
What to do: Fix the service. The excerpt is its own reason.
Exit code: None. sipnab writes the call without the service’s analysis.
answered with more than {MAX_ANSWER_BYTES} bytes
The detail an [[vcon.enrich]] records when the service’s answer was larger than 16 MiB, which sipnab does not read.
What to do: Make the service answer with less: an analysis, not the audio.
Exit code: None. sipnab writes the call without the service’s analysis.
analysis {i} has encoding '{encoding}'; core-04 allows none, json and base64url
The detail of a malformed outcome: entry {i} of an [[vcon.enrich]] service’s analysis has an encoding core-04 does not define. {encoding} is the value. sipnab keeps none of that answer.
What to do: Answer with encodingnone, json or base64url.
Exit code: None. sipnab writes the call without the service’s analysis.
is a {WTF_TYPE} with encoding '{encoding}'; the WTF draft requires json
Part of the detail of a malformed outcome, after analysis {i}: a [[vcon.enrich]] service answered with a wtf_transcription whose encoding is not json. {WTF_TYPE} is wtf_transcription and {encoding} the value sent. Section 6.1 of draft-howe-vcon-wtf-extension-02 requires json. sipnab keeps none of that answer.
What to do: Send the transcription as a JSON object with encodingjson.
Exit code: None. sipnab writes the call without the service’s analysis.
is a {WTF_TYPE} whose {what}
Part of the detail of a malformed outcome, after analysis {i}: a wtf_transcription from a [[vcon.enrich]] service lacks a member the WTF draft requires, or holds one out of range. {what} names it, such as segments[0] ends at 1, not after its start 2 or metadata has no model string. sipnab keeps none of that answer.
What to do: Fix the service’s transcription to carry the transcript, segments and metadata members the WTF transcription check in the vCon guide lists.
Exit code: None. sipnab writes the call without the service’s analysis.
a provenance whose model has no {key}
Part of the detail of a malformed outcome, after analysis {i} has: an analysis entry from a [[vcon.enrich]] service carries its own provenance record, and the record’s model has no vendor or no name. {key} is the missing member. Section 4.2.1 of draft-howe-vcon-provenance-00 requires both. sipnab keeps none of that answer.
What to do: Send model.vendor and model.name, or leave provenance out and let sipnab write it from the entry’s vendor and product.
Exit code: None. sipnab writes the call without the service’s analysis.
the answer has attachments, and sipnab carries an enrichment's attachment only for a [[vcon.enrich]] with lawful_basis = true, and only a {LAWFUL_BASIS} one
The detail of a malformed outcome: a [[vcon.enrich]] service answered with an attachments list, and its entry does not set lawful_basis = true. {LAWFUL_BASIS} is lawful_basis. sipnab writes no lawful basis of its own and carries one from a service only when you allow it. sipnab keeps none of that answer.
What to do: Set lawful_basis = true on the [[vcon.enrich]] entry if that service is the source of the lawful basis you want carried, or remove attachments from its answer.
Exit code: None. sipnab writes the call without the service’s analysis.
has a {other} member, which sipnab cannot carry as sent
Part of the detail of a malformed outcome, after attachment {i}: a lawful basis attachment from a [[vcon.enrich]] service has a member other than purpose, start, party, dialog, encoding, body and mediatype. {other} is the member. sipnab carries the attachment unchanged or not at all. sipnab keeps none of that answer.
What to do: Send the attachment with those members only.
Exit code: None. sipnab writes the call without the service’s analysis.
has a purpose other than {LAWFUL_BASIS}
Part of the detail of a malformed outcome, after attachment {i}: an attachment from a [[vcon.enrich]] service with lawful_basis = true has a purpose other than lawful_basis. {LAWFUL_BASIS} is lawful_basis. sipnab carries no other kind of attachment from a service. sipnab keeps none of that answer.
What to do: Answer with lawful basis attachments only, purposelawful_basis.
Exit code: None. sipnab writes the call without the service’s analysis.
has a body whose {what}
Part of the detail of a malformed outcome, after attachment {i}: the body of a lawful basis attachment from a [[vcon.enrich]] service lacks a member section 5.2 of draft-howe-vcon-lawful-basis-02 requires, or holds one of the wrong type. {what} names it, such as purpose_grants[0] has no boolean granted. sipnab keeps none of that answer.
What to do: Fix the body the service sends to the shape of section 5.2.
Exit code: None. sipnab writes the call without the service’s analysis.
G.729 tables (sipnab g729)
sipnab g729 install and sipnab g729 status print these messages.
G.729 decoding describes the command. Each one stops the command
with exit code 1 and installs nothing. A table file already in place stays as
it was.
No place to install {TABLE_FILE_NAME}: give --g729-tables PATH, set [g729] tables, or set HOME
sipnab g729 install has nowhere to write the table file. The command line
has no --g729-tables, the config file has no [g729] tables, and
neither HOME nor XDG_CONFIG_HOME names a directory, which is usual for a
service account. {TABLE_FILE_NAME} is g729-tables.bin.
What to do: Give the path: sipnab g729 install --g729-tables /srv/sipnab/g729-tables.bin,
and give the same path to the capture runs, or set [g729] tables.
Exit code: 1.
Refused {what}: its sha256 is {actual}, expected {PACKAGE_SHA256} (the ITU-T G.729 (06/2012) Release 3 package). Nothing was installed.
The package is not the one sipnab pins. {what} is the zip --from named,
or “the download from” and the itu.int URL. {actual} is the sha256 of what
sipnab read, and {PACKAGE_SHA256} is the pinned one,
979680ff3b52b13a5701453178efd32b53e340114638fd330fdb6669eec86620. A
download that stopped part way, a proxy’s error page, or another release of
the package each give another hash.
What to do: Download the package again from the URL sipnab g729 install
prints, check that sha256sum prints the pinned hash, and run the command
again. To install from a copy, give --from the zip itself.
Exit code: 1.
Refused the table file {}: its values sha256 is {}, expected {}. Nothing was installed.
--from named a table file whose layout is right but whose values differ
from the ones sipnab pins. The placeholders are the file, the sha256 of its
values, and the pinned one. Someone changed the file, or built it from a
different package.
What to do: Copy the table file again from a host where
sipnab g729 status reports the pinned values hash, or install from the ITU-T
package instead.
Exit code: 1.
Refused the table file {}: {other}. Nothing was installed.
--from named a file that starts like a table file but is not one: the
wrong version, the wrong length, or an entry of the wrong size. {other} says
which.
What to do: Copy the file again. A copy cut short is the usual cause.
Exit code: 1.
Refused {}: {e}. Nothing was installed.
The importer could not build the tables from the package. {} is the zip or
directory, and {e} is the reason: a pinned source file is not in it (the
directory does not hold the extracted package, or holds part of it), or the
imported values do not hash to the pinned value, and the message names both
hashes.
What to do: Give --from the whole package zip, or the directory
python3 scripts/fetch-g729-vectors.py fills (crates/g729/test-vectors/itu-source).
Exit code: 1.
Cannot read {}: {e}
--from names a file sipnab cannot read. {e} is the operating system’s
reason.
What to do: Check the path and its permissions.
Exit code: 1.
Cannot create {}: {e}
sipnab cannot make the directory the table file goes in. {e} is the
operating system’s reason.
What to do: Create the directory, or give --g729-tables a path in a
directory you can write.
Exit code: 1.
Cannot write the download in {}: {e}
sipnab cannot write the downloaded package to a temporary file in the table
file’s directory, where the importer reads it. {e} is the operating
system’s reason, often a full disk.
What to do: Free about 19 MB in that directory, or choose another with
--g729-tables.
Exit code: 1.
Cannot write {}: {e}
sipnab cannot write the table file. {e} is the operating system’s reason.
What to do: Check the directory’s permissions and free space.
Exit code: 1.
Cannot set the mode of {}: {e}
sipnab wrote the table file but could not set its mode to 0644, so other
accounts, such as a service’s, may not read it.
What to do: Set it yourself with chmod 644.
Exit code: 1.
Downloading {url} failed: {e}
The download from itu.int did not complete. {e} is the reason: no route,
a refused certificate, or one of the two answers below.
What to do: Check that the host reaches www.itu.int over HTTPS. A host
that cannot: download the package elsewhere and run
sipnab g729 install --from <the zip>.
Exit code: 1.
itu.int answered {status}
itu.int answered the download with an HTTP status other than 200. It is
part of the Downloading {url} failed message.
What to do: Try again later, or download the package with a browser and
install it with --from.
Exit code: 1.
itu.int answered more than {PACKAGE_BYTES} bytes, more than the package
The answer is larger than the package (18,476,968 bytes), so it is not the
package. It is part of the Downloading {url} failed message.
What to do: Download the package with a browser, check its sha256, and
install it with --from.
Exit code: 1.
Startup, privileges and the process
--allow-coredump: a core dump would contain the archive password this run holds
A warning that sipnab prints in this case:
this run holds an archive password; and
the command line includes --allow-coredump.
The password comes from --archive-password, --archive-password-file, --archive-password-command, --archive-password-stdin, the SIPNAB_ARCHIVE_PASSWORD environment variable or a systemd credentials directory.
sipnab normally disables core dumps while it holds a password.
With --allow-coredump it leaves them enabled. So a crash could write the password to a core file.
What to do: Remove --allow-coredump to have sipnab disable core dumps while it holds the password. Keep it only if a core file containing the password is acceptable.
Exit code: None. This is a warning, and the run continues.
Capture thread exited before signaling ready
sipnab started its capture thread. It waited for the thread to report that its source (interface, file or socket) was open. But the thread ended without reporting either success or failure.
What to do: Re-run with SIPNAB_LOG=debug to see what the capture thread logged before it ended. Report the output if the cause is not shown.
Exit code: 1.
Could not block privilege escalation through exec: {e}
At startup sipnab sets the Linux PR_SET_NO_NEW_PRIVS flag. That flag stops any program it later starts from gaining privileges through a setuid or setgid file.
The prctl call that sets the flag failed. Or the flag read back as not set afterwards.
{e} holds that reason, including the operating-system error.
sipnab logs this as a warning, and continues without that protection.
What to do: No setting changes this step, and the run continues either way. The text after the colon names the system-call error to investigate on the host (the kernel or container must allow prctl(PR_SET_NO_NEW_PRIVS)).
Exit code: None. This is a warning, and the run continues.
Could not start the scanner-kill worker process: {e}. The --kill-scanner defense is DISABLED for this run; detection, alerting and reporting continue.
sipnab answers SIP scanners from a separate worker process (a copy of its own executable), and starting that process failed. {e} is the operating system error. The scanner-kill response (--kill-scanner, [security] kill_scanner or -K) is off for this run. Detection, alerting and reporting continue.
What to do:
Check that sipnab can still find and execute its executable at the path it started from.
Check that the system allows it to create processes.
Then restart the run.
Exit code: None. sipnab logs the error, and the run continues.
Failed to chroot: {e}
--chroot or [privilege] chroot asked sipnab to change its root directory after opening the capture. The change failed.
{e} names the failing call (chroot or chdir(/)) and the reason. Or it says the path is not valid UTF-8, or contains a null byte.
Changing the root directory requires root privileges.
What to do: Run sipnab as root when using --chroot, make sure the directory exists, or remove --chroot and [privilege] chroot.
Exit code: 1.
Failed to disable core dumps: {e}
The run loads decryption keys (--tls-key, --keylog, --keylog-fd, --srtp-keys or --dtls-keylog).
So sipnab tells the operating system to exclude the process from core dumps. This keeps keys out of core files.
The operating system refused.
{e} names the failing call, and says that --allow-coredump runs anyway.
What to do: Pass --allow-coredump if a core file containing key material is acceptable. Otherwise, run on a system that allows the call.
Exit code: 1.
Failed to drop privileges: {e}
Running as root, sipnab switches to an unprivileged account after opening the capture, and the switch failed. The account is --user, else [privilege] user, else nobody. {e} gives the reason, for example an account that does not exist or a credential call that failed.
What to do: Name an existing account with --user <USER> or [privilege] user, or pass --no-priv-drop to keep the current account.
Exit code: 1.
Failed to spawn processing thread: {e}
In the TUI, the operating system refused to create the thread that reads packets into the call and stream lists. {e} is the operating system error.
What to do: sipnab offers no setting for this step. Act on the operating system reason in {e} and run again.
Exit code: 1.
Failed to start capture: {e}
sipnab could not create the capture thread. {e} is the error from starting it (for example “Failed to spawn live capture thread”).
What to do: Check the system’s process and thread limits and available memory, then run again.
Exit code: 1.
--kill-spoof raw requires a raw socket but it could not be opened: {e}. Grant CAP_NET_RAW (sipnab --setup-caps / run under sudo) or use --kill-spoof ephemeral.
--kill-spoof raw requires a raw network socket. With it, responses sent to SIP scanners carry the scanned party’s address and port as their source.
Opening the socket failed.
{e} is the operating system error. Typically it is a missing CAP_NET_RAW capability (the Linux permission to open raw sockets).
What to do: Run sipnab --setup-caps once, or run the command under sudo, to grant CAP_NET_RAW. Alternatively use --kill-spoof ephemeral, or --kill-spoof auto, which falls back to sipnab’s own port when the socket is unavailable.
Exit code: 1.
Permission denied on '{}'. Grant capture capabilities once (Linux), then re-run without sudo:\n sipnab --setup-caps\n # or run this invocation under sudo:\n sudo sipnab\n # equivalent manual step:\n sudo setcap cap_net_raw,cap_net_admin+ep $(which sipnab)
sipnab lacks the permission to open the capture device. {} names the interfaces involved. The message lists three ways to grant the capture capabilities.
What to do: Run sipnab --setup-caps once and re-run without sudo, run the command under sudo, or run sudo setcap cap_net_raw,cap_net_admin+ep $(which sipnab).
Exit code: 1.
Processing thread panicked: {}
When the TUI closed, sipnab found that the packet-processing thread had ended with a panic (an internal failure).
{} is the panic message. Or it is <non-string panic payload> when the panic carried no text.
Release builds use panic = "abort". That ends the whole process at the panic.
So this line appears only in builds that unwind on panic.
What to do: This is an internal failure in sipnab, not a setting. Report it with the command line you used and the log output.
Exit code: None. sipnab logs this during shutdown, and the TUI’s own result decides the exit status.
Scanner-kill: raw socket unavailable ({e}); falling back to ephemeral source port. Kill responses will come from sipnab's own port.
A warning: the default --kill-spoof auto tried to open a raw socket, so that scanner responses could carry the scanned party’s address. The operating system refused ({e}).
sipnab sends the responses from an ordinary UDP socket instead.
So they come from sipnab’s own address and port.
What to do: To send spoofed responses, grant CAP_NET_RAW with sipnab --setup-caps or run under sudo. To use sipnab’s own port without this warning, pass --kill-spoof ephemeral.
Exit code: None. This is a warning, and the run continues.
sipnab: the terminal UI could not start: {e}. It needs a terminal; add -N for a run without one.
The terminal UI returned an error, so the run ends with exit 1. {e} is the error. sipnab prints this line to standard error after it restores the terminal, so it is visible even with logging off.
What to do: Run sipnab in an interactive terminal, or add -N to run without the TUI.
Exit code: 1.
TUI error: {e}
The terminal UI returned an error. Setting up the terminal (raw mode, the alternate screen), drawing a frame, or reading a key or mouse event failed. {e} is that error. The line sipnab: the terminal UI could not start: ... follows it on standard error.
What to do: Run sipnab in an interactive terminal, or add -N for a run without the TUI.
Exit code: 1.
Analysis warnings
--since/--until: no dialog's first message falls in {window}; this capture's dialogs begin between {} and {}
The time window that --since and --until give holds none of the capture’s dialogs. So every listing is empty.
{window} is the window, written [start, end). It shows unbounded for a side you did not give.
The two {} are the first-message times of the earliest and the latest dialog in the capture.
sipnab prints this line on stderr, so a JSON stream on stdout stays valid.
What to do: Move the window to cover the times the line names.
Exit code: None. This is a notice, and the run continues.
--since/--until: no dialog in {window}; the capture holds no dialog
You gave --since or --until, and the capture holds no dialog at all, so every listing is empty. {window} is the window, written [start, end), with unbounded for a side you did not give.
What to do: Check that the input holds SIP traffic.
Exit code: None. This is a notice, and the run continues.
capture quality: {}. THIS ANALYSIS IS INCOMPLETE — the counts above are what sipnab RECEIVED AND UNDERSTOOD, not what crossed the wire. See docs/tuning-capture.md.
The capture lost or could not read part of the traffic. The {} part lists each kind of loss, with a semicolon between them. All totals in the output describe what sipnab received and understood, not everything that crossed the wire.
What to do: Follow the advice in each listed part. Tuning capture describes the capture settings.
Exit code: None. This is a warning, and the run continues.
Fix the decode before reading anything into the zero above: convert the capture (editcap -T ether) or open an issue naming the number(s) reported.
The remedy for frames sipnab could not decode.
What to do: Convert the capture (editcap -T ether) or open an issue naming the reported number.
Exit code: None. This is a warning, and the run continues.
{snapped} frame(s) arrived truncated by the capture's snaplen and {snapped_undecodable} of them were cut too short to decode at all, so nothing in those was analyzed (raise --snaplen)
Part of the capture-quality summary.
The snapshot length (snaplen) is the most bytes the capture keeps of each packet.
It cut {snapped} frames short.
{snapped_undecodable} of them were too short to decode at all. So sipnab analyzed nothing in those frames.
What to do: Raise --snaplen.
Exit code: None. This is a warning, and the run continues.
{snapped} frame(s) arrived truncated by the capture's snaplen (headers kept, payload cut short — raise --snaplen if you need RTP payload, audio export or a faithful -O re-emit)
Part of the capture-quality summary. The capture’s snapshot length (snaplen, the most bytes the capture stores per frame) cut {snapped} frames short. sipnab kept and analyzed the headers, and the payload is missing.
What to do: Raise --snaplen if you need RTP payload, audio export or a complete -O copy.
Exit code: None. This is a warning, and the run continues.
{intact_undecodable} frame(s) reached sipnab intact and could not be decoded at all, so nothing in them was analyzed (see the NOT DECODED line above for which link types, EtherTypes and IP protocols)
Part of the capture-quality summary. {intact_undecodable} frames arrived complete, but no sipnab decoder could read them, so sipnab analyzed nothing in them. The NOT DECODED line names the link types, EtherTypes and IP protocols.
What to do: See the NOT DECODED line for the reasons. If the link type is the cause, convert the capture (for example editcap -T ether).
Exit code: None. This is a warning, and the run continues.
{holes} hole(s) in TCP streams, {hole_bytes} byte(s) of sequence space the capture never held, were skipped: reading resumed at the next SIP message behind each, and a message the hole cut is lost (packets the capture point missed)
Part of the capture-quality summary. TCP streams had {holes} gaps, totaling {hole_bytes} bytes, that the capture never contained. sipnab skipped each gap and resumed reading at the next SIP message after it. A SIP message that a gap cuts through goes missing from the analysis.
What to do: Capture closer to the traffic, or with a larger buffer, so that the capture point does not miss packets.
Exit code: None. This is a warning, and the run continues.
IMPOSSIBLE RATE: {count} stream(s) carry more payload than their codec can produce — worst is {label} at {mult:.1}x its ceiling. The most common cause is the same traffic read twice: a directory holding a capture and its backup, or one call captured at two hops. Counts and rates in this run are inflated by that factor. sipnab does not de-duplicate, because two vantage points on one call are a legitimate input.
At least one RTP stream carried more payload per second than its codec can produce. That means more than 15% over the codec’s fixed rate, measured over at least 0.5 seconds.
{count} is the number of streams.
{label} names the worst one (codec, SSRC, source and destination).
{mult:.1} is how many times over the ceiling that stream ran.
sipnab does not check variable-rate codecs such as Opus.
What to do: Check the -I input for the same traffic read twice. For example, a directory holding a capture and its backup. Run again with one copy.
If you meant to supply two captures of one call from different points, the counts include both by design.
Exit code: None. This is a warning, and the run continues.
--kill-ua {pattern} names a User-Agent for the scanner detector, and nothing in this run builds that detector — so the pattern is read by nobody and the run would report no scanners whether or not one is there. Add --kill-scanner (or set [security] kill_scanner = true) to arm the detection this pattern feeds. On a live capture --kill-scanner also arms the response path, which is why sipnab will not turn it on for you.
--kill-ua adds a User-Agent pattern for the scanner detector. This run does not build that detector, because you set neither --kill-scanner nor [security] kill_scanner = true.
{pattern} is the pattern you gave.
sipnab does not turn scanner detection on by itself. On a live capture that would also enable sending SIP responses to the detected scanners.
What to do: Add --kill-scanner or set [security] kill_scanner = true in the configuration file, or remove --kill-ua.
Exit code: 2.
{msgs} message(s) evicted from retained dialogs by idle compaction
Part of the retention summary. Idle compaction removed {msgs} SIP messages from dialogs that sipnab kept.
What to do: Raise --limit or --max-streams to keep more.
Exit code: None. This is a warning, and the run continues.
{dropped} new dialog(s) refused at capacity (--no-rotate keeps the earliest)
Part of the retention summary. sipnab refused {dropped} new dialogs because the dialog store was full, and --no-rotate keeps the earliest dialogs.
What to do: Raise --limit, or drop --no-rotate so that sipnab discards the oldest dialogs instead.
Exit code: None. This is a warning, and the run continues.
No SIP signaling found, but {rtp_packets} RTP packets across {streams} stream(s) were parsed.
sipnab found no SIP, but it parsed {rtp_packets} RTP packets in {streams} streams, so the capture was readable.
What to do: If you expected signaling, check the capture point.
Exit code: None. This is a warning, and the run continues.
No SIP traffic found, but this capture is not empty: {} of {} STUN/TURN transaction(s) went unanswered — {} sent {} to {} {} time(s) and got nothing back.
sipnab found no SIP, but STUN/TURN requests (the messages an endpoint uses to learn its public address) got no answer. The numbers are the unanswered transactions, the total transactions, and the first unanswered request’s sender, method, destination and attempt count.
What to do: Read the next two lines.
Exit code: None. This is a warning, and the run continues.
No SIP traffic found. Check that the capture contains SIP packets (typically UDP port 5060-5061).
The capture held no SIP that sipnab found, and nothing else explains it.
What to do: Check that the capture contains SIP (usually UDP port 5060-5061).
Exit code: None. This is a warning, and the run continues.
No SIP traffic was decoded — but {} of {frames_read} frame(s){share} could not be decoded at all, so this is not a finding that the capture contains no SIP. Undecodable: {}.
sipnab decoded no SIP, and some frames failed to decode at all. So the zero is not a finding that the capture holds no SIP.
The numbers are the undecodable frames, the frames read, and the reasons.
What to do: Read the next line.
Exit code: None. This is a warning, and the run continues.
No SIP traffic was decoded, but TLS application data in this capture could not be decrypted (see above), so this is not a finding that the capture contains no SIP.
sipnab decoded no SIP, and it could not decrypt TLS traffic in the capture, so SIP may be inside that traffic.
What to do: Follow the TLS decryption lines printed above.
Exit code: None. This is a warning, and the run continues.
NOT ANALYZED: {} further SIP message(s) were seen on ports outside --portrange and are in none of the totals above. Busiest: {}. Re-run with --portrange 1-65535 to include them.
When sipnab reads a capture file, --portrange selects which ports carry SIP signaling.
sipnab saw messages that look like SIP on other ports.
It did not analyze them, and left them out of every total.
The first {} is the count.
The second lists up to five of the busiest ports, with message counts. A port here is the destination port of requests and the source port of responses.
What to do: Run again with --portrange widened to include the listed ports, or with --portrange 1-65535 to include all of them.
Exit code: None. This is a warning, and the run continues.
NOT ANALYZED: {} SIP-over-WebSocket message(s) arrived on ports outside the WebSocket port set ({}) and are in none of the totals above. Busiest: {}. Re-run with --ws-portrange covering them (e.g. --ws-portrange 1-65535) to include them.
sipnab unwrapped some messages as SIP carried in WebSocket frames. But they were on ports outside the WebSocket port set.
So sipnab did not analyze them, and every total leaves them out.
The first {} is the message count.
The second is the current port set (default 80, 443, 8080, 8443, or the --ws-portrange range).
The third lists up to five of the busiest ports, with message counts.
What to do: Run again with --ws-portrange covering those ports (for example --ws-portrange 1-65535), or set [capture] ws_ports in the configuration file.
Exit code: None. This is a warning, and the run continues.
NOT DECODED: {} of {frames_read} frame(s)
Start of the NOT DECODED notice. The first number is how many frames sipnab could not decode, out of {frames_read} frames read. A percentage follows when {frames_read} is above zero.
What to do: Read the reasons on the same line.
Exit code: None. This is a warning, and the run continues.
NOTHING IN THIS CAPTURE WAS READ — every frame failed to decode, so the totals above describe no traffic whatsoever and a zero among them is not evidence of absence.
Every frame in the capture failed to decode.
So every total sipnab printed describes no traffic.
A zero is not evidence that something is absent.
What to do: Convert the capture to a link type sipnab reads (for example with editcap -T ether). Or open an issue naming the reported number.
Exit code: None. This is a warning, and the run continues.
{rotated} oldest dialog(s) discarded at capacity by rotation
Part of the retention summary. sipnab discarded {rotated} of the oldest dialogs because the dialog store was full.
What to do: Raise --limit to keep more dialogs.
Exit code: None. This is a warning, and the run continues.
{if_dropped} packet(s) dropped by the interface or its driver (a bigger buffer cannot recover these — check the NIC and its offloads)
Part of the capture-quality summary. The network interface or its driver dropped {if_dropped} packets before they reached the capture library.
What to do: A larger buffer does not recover these. Check the network card and its offload settings.
Exit code: None. This is a warning, and the run continues.
{dropped} packet(s) dropped by the kernel capture buffer (raise -B/--buffer, narrow the BPF filter, or lower --snaplen)
Part of the capture-quality summary. The kernel capture buffer was full and lost {dropped} packets.
What to do: Raise -B/--buffer, narrow the BPF filter, or lower --snaplen.
Exit code: None. This is a warning, and the run continues.
{bad_ts} packet(s) had a corrupt capture timestamp and were stamped with the wall clock (timing analysis is unreliable for this run)
Part of the capture-quality summary.
{bad_ts} packets had a corrupt timestamp in the capture.
sipnab gave them the current clock time instead.
So timing figures for this run are not reliable.
What to do: Capture again, or repair the capture file. sipnab has no option that recovers the original timestamps.
Exit code: None. This is a warning, and the run continues.
; plus {} further frame(s) whose reason was not retained (the capture carried more distinct reasons than the tally holds)
Continues the NOT DECODED notice. {} more frames failed to decode for a reason that the tally had no room to keep.
What to do: This part needs no action. The count is exact.
Exit code: None. This is a warning, and the run continues.
produced nothing and are in none of the counts above. Reasons: {}
Continues the NOT DECODED notice. Those frames are in none of the totals printed above. {} lists each reason with its number (link type, EtherType or IP protocol) and count.
What to do: Convert the capture (for example with editcap -T ether) or open an issue naming the reported number.
Exit code: None. This is a warning, and the run continues.
{flags} refused: security detection is built only by the headless single-capture path, and this run is {path}. Nothing would be detected and no finding reported, so an empty result would not be an all-clear — which is why this is refused rather than warned about. To detect, {remedy}.
You gave security detection flags on a run that uses the parallel offline reader. That reader builds no detectors.
sipnab picks that mode when --cores is above 1 with -I, and without multi-device capture.
{flags} lists the detection settings that the run asked for. They come from --kill-scanner, -K/--kill-target, --fraud-detect, --digest-leak and --reg-flood, including ones turned on in the configuration file.
{path} is the --cores parallel offline reader.
{remedy} is drop --cores (the single-core headless read detects).
What to do: Do one of these:
Remove --cores (or set it to 1). The run then reads on a single core and builds the detectors.
Remove the listed detection settings.
Exit code: 2.
retention: {}. The message and packet counts above are what sipnab READ, not what it kept — raise --limit, or --max-streams, to keep more.
sipnab read more than it kept. The {} part lists what sipnab dropped (messages evicted, new dialogs refused, oldest dialogs discarded), separated by semicolons. The message and packet totals printed above count what sipnab read, not what it kept.
What to do: Raise --limit, or --max-streams, to keep more.
Exit code: None. This is a warning, and the run continues.
STIR/SHAKEN: unparseable Identity header: {e}
--stir-shaken logs every Identity header in each SIP message. The Identity header is the STIR/SHAKEN caller-ID signature, a JWT called a PASSporT.
sipnab could not parse one Identity header, for one of these reasons. {e} says which.
it does not have three parts separated by dots;
its payload is not valid base64url;
the payload is not the expected JSON.
What to do: No flag changes this. The message describes the SIP message as sipnab received it. Inspect the Identity header of that message in the capture.
Exit code: None. This is a warning, and the run continues.
That is a NAT-discovery failure, not a missing capture. An endpoint that cannot learn its reflexive address advertises its PRIVATE address in SDP, and the far end then sends media to somewhere it cannot reach — a call that signals cleanly and carries audio one way.
Explains the unanswered STUN/TURN requests.
An endpoint that cannot learn its public address advertises its private one in SDP. SDP is the media description in the call setup.
That gives one-way audio.
What to do: Read the next line.
Exit code: None. This is a warning, and the run continues.
The requests drew no reply at all rather than a refusal, which points at something in the path discarding them rather than at the server. On school, campus and corporate networks that is most often a security appliance — web filter, secure web gateway, firewall or IPS — dropping UDP it does not recognize. Confirm whether one sits in this path and whether it permits UDP to the STUN/TURN port.
The STUN/TURN requests drew no reply at all, which points at something in the path dropping UDP rather than at the server.
What to do:
Check whether a web filter, secure web gateway, firewall or IPS sits in the path.
Check whether it permits UDP to the STUN/TURN port.
Exit code: None. This is a warning, and the run continues.
THIS ANALYSIS IS MOSTLY BLIND — the totals above describe the minority of the capture sipnab could read, so a zero among them is not evidence of absence.
Half or more of the frames failed to decode.
So the totals describe only the part of the capture sipnab could read.
A zero is not evidence that something is absent.
What to do: Convert the capture (for example with editcap -T ether) or open an issue naming the reported number.
Exit code: None. This is a warning, and the run continues.
Tip: Use 'sipnab -N -I file.pcap --hexdump' to inspect raw packet content.
sipnab prints this after the no-SIP line.
What to do: Run sipnab -N -I file.pcap --hexdump to inspect the raw packets.
Exit code: None. This is a warning, and the run continues.
{finding} Use --report to see stream details.
sipnab adds this to the line above when you did not give --report. {finding} is that line.
What to do: Add --report to see the stream details.
Exit code: None. This is a warning, and the run continues.
Library and parser errors
{what} contains invalid UTF-8
Library parser error. Bytes that must be text are not valid UTF-8.
{what} is SIP first line or SDP body.
In the sipnab program, sipnab drops a SIP-looking packet that fails this way. It logs it only at debug level (SIPNAB_LOG=debug) as SIP parse error: ....
-x/--quiet-bad-parse silences that line.
sipnab does not use a SIP message body that fails this way for media setup. It prints no message for it.
What to do: The SIP first line or SDP body contained bytes that are not UTF-8 text.
Exit code: None. The error goes back to the program that calls the library.
empty {what}
Library parser error: the parser received empty input.
{what} names the expected input: SIP message (from parse_sip or parse_sip_bytes) or SDP body (from parse_sdp).
In the sipnab program, sipnab drops a SIP-looking packet that fails this way. It logs it only at debug level (SIPNAB_LOG=debug) as SIP parse error: followed by this text.
-x/--quiet-bad-parse silences that line.
sipnab does not use a SIP message body that fails this way for media setup. It prints no message for it.
What to do: The input was zero bytes long. Library callers should pass the whole SIP message or SDP body.
Exit code: None. The error goes back to the program that calls the library.
Packet decoder error (library surface). A frame nests more encapsulation layers than the limit allows.
Encapsulation layers are tunnels such as IP-in-IP, GRE, MPLS-in-IP, AH, ESP or UDP tunnels.
{kind} is the layer that went over the limit.
{limit} is the limit, 5.
The limit protects the decoder from crafted frames.
In the sipnab program, this text appears only in debug logging (SIPNAB_LOG=debug) as Skipping unparseable packet: ....
sipnab counts the frame in the headless (-N) end-of-run NOT DECODED summary, and in the sipnab_capture_undecodable_frames_total metric. The run continues.
What to do: No setting changes the limit. sipnab does not decode frames nested this deeply.
Exit code: None. This is a warning, and the run continues.
failed to decode {what}
Packet decoder error from the library: sipnab could not decode a link or network layer of a captured frame.
{what} names the layer, such as Ethernet packet, IP from encapsulated Ethernet frame or WebSocket frame.
When the capture cut the frame short (snaplen), sipnab counts the frame as truncated rather than as a decode error.
In the sipnab program this text appears only in debug logging (SIPNAB_LOG=debug). It is on a line that starts with Skipping and ends with this text.
sipnab counts the frame in the headless (-N) end-of-run NOT DECODED summary, and in the sipnab_capture_undecodable_frames_total metric. The run continues.
What to do: If the summary reports the frames as truncated, capture again with a larger --snaplen. Otherwise the frame is in a format the decoder does not read.
Exit code: None. The error goes back to the program that calls the library, and a sipnab run skips the frame and continues.
gzip-compressed capture; decompress it first (sipnab's file loaders and decompress_capture do this automatically)
Library error from PcapReader::new: the bytes passed to it are still gzip-compressed.
decompress_capture and the file loaders in sipnab decompress before reading.
So only a program that calls PcapReader::new directly on compressed bytes sees this.
What to do: Pass the bytes through sipnab::capture::pcap_reader::decompress_capture first, as the message says, and give the result to PcapReader::new.
Exit code: None. The error goes back to the program that calls the library.
gzip-compressed capture inflates past the {limit}-byte safety cap; raise --max-gunzip-bytes (or [limits] max_gunzip_bytes) for a capture you trust, or decompress it manually (e.g. gunzip) and open the raw file
Decompressing a gzip-compressed capture would produce more than {limit} bytes. So decompression stopped.
That limit is the in-memory safety cap (default 1 GiB, 1073741824 bytes).
The sipnab command opens -I files through libpcap and its archive layer. Those report problems in their own words.
This text comes from the library reader PcapReader::new or decompress_capture, and from the WebAssembly build’s file loader.
What to do: Decompress the file with a separate tool such as gunzip and open the raw capture. A program that uses the library raises the cap with sipnab::capture::pcap_reader::set_max_gunzip_bytes.
Exit code: None. The error goes back to the program that calls the library.
gzip stream is corrupt or truncated: {source}
Decompressing a gzip-compressed capture failed, because the compressed data has damage or ends early.
{source} is the error from the decompression step.
The sipnab command opens -I files through libpcap and its archive layer. Those report problems in their own words.
This text comes from the library reader PcapReader::new or decompress_capture, and from the WebAssembly build’s file loader.
What to do: Obtain a complete, undamaged copy of the .gz file.
Exit code: None. The error goes back to the program that calls the library.
{what} has no IP layer
Packet decoder error (library surface). The frame carries no IP layer.
Examples are ARP, a PPP frame without IP, a loopback frame of another address family, or an encapsulation that the decoder recognizes but cannot read.
{what} names it.
In the sipnab program, this text appears only in debug logging (SIPNAB_LOG=debug) as Skipping unparseable packet: ....
sipnab counts the frame in the headless (-N) end-of-run NOT DECODED summary, and in the sipnab_capture_undecodable_frames_total metric. The run continues.
What to do: The run needs no action. Frames without IP carry no SIP or RTP.
Exit code: None. This is a warning, and the run continues.
ICMP packets are not processed by sipnab
The packet decoder (parse_packet, part of the library) does not turn ICMP or ICMPv6 packets into SIP or RTP data. It returns this error for them.
Before it returns, the native decoder records an ICMP error message that quotes an earlier packet. The record is evidence for the matching dialog.
In the sipnab program this text appears only in debug logging (SIPNAB_LOG=debug). It is on a line that starts with Skipping and ends with this text.
sipnab does not count the packet as undecodable.
What to do: You need to do nothing. Every ICMP packet ends this way after sipnab records any error evidence it carries.
Exit code: None. The error goes back to the program that calls the library, and a sipnab run skips the frame and continues.
invalid SIP first line '{line}': {reason}
Library parser error: the first line ends in SIP/2.0. So the parser reads it as a SIP request line. But it does not have the shape METHOD Request-URI SIP/2.0.
{line} is the line.
{reason} is the problem. It is no space before SIP version when no Request-URI sits between the method and the version.
In the sipnab program, sipnab drops a SIP-looking packet that fails this way. It logs it only at debug level (SIPNAB_LOG=debug) as SIP parse error: followed by this text.
-x/--quiet-bad-parse silences that line.
What to do: The request line has the wrong form. It must hold a method, a Request-URI and SIP/2.0, separated by spaces.
Exit code: None. The error goes back to the program that calls the library.
invalid SIP status code: '{code}'
Library parser error: the first line starts with SIP/2.0 . So the parser reads it as a SIP response status line. But the word after it is not a whole number from 0 to 65535.
{code} is that word.
In the sipnab program, sipnab drops a SIP-looking packet that fails this way. It logs it only at debug level (SIPNAB_LOG=debug) as SIP parse error: followed by this text.
-x/--quiet-bad-parse silences that line.
What to do: The status line has the wrong form. It must be SIP/2.0, a numeric status code and an optional reason phrase, such as SIP/2.0 200 OK.
Exit code: None. The error goes back to the program that calls the library.
Microsoft Network Monitor (.cap) format is not supported. Convert to pcap with: editcap -F pcap input.cap output.pcap
The file starts with the Microsoft Network Monitor signature (magic 0x55424d47). The built-in reader cannot read that capture format.
The sipnab command opens -I files through libpcap and its archive layer. Those report problems in their own words.
This text comes from the library reader PcapReader::new or decompress_capture, and from the WebAssembly build’s file loader.
What to do: Convert the file to pcap with the editcap -F pcap input.cap output.pcap command that the message gives, then open the converted file.
Exit code: None. The error goes back to the program that calls the library.
no CRLF found — not a SIP message
Library parser error: the data contains no CRLF, so it cannot be a SIP message. CRLF is carriage return and line feed, the line ending SIP requires.
In the sipnab program, sipnab drops a SIP-looking packet that fails this way. It logs it only at debug level (SIPNAB_LOG=debug) as SIP parse error: followed by this text.
-x/--quiet-bad-parse silences that line.
What to do: The input is not a SIP message, or it uses bare line feeds. SIP lines must end in CRLF.
Exit code: None. The error goes back to the program that calls the library.
no IP payload in {what}
Packet decoder error from the library: the frame has an IP header, but no payload behind it to read.
{what} names the packet (packet or inner packet).
In the sipnab program this text appears only in debug logging (SIPNAB_LOG=debug). It is on a line that starts with Skipping and ends with this text.
sipnab counts the frame in the headless (-N) end-of-run NOT DECODED summary, and in the sipnab_capture_undecodable_frames_total metric. The run continues.
What to do: The run needs nothing from you. The frame carries nothing that sipnab can analyze.
Exit code: None. The error goes back to the program that calls the library, and a sipnab run skips the frame and continues.
not a pcap/pcapng file (magic: 0x{magic:08x}). Supported formats: .pcap, .pcapng, .cap (pcap format), and their gzip-compressed variants (.pcap.gz, .pcapng.gz)
The data does not start with a pcap, pcapng or Network Monitor signature. So it is not a capture file the built-in reader knows.
{magic} is the first four bytes read as a little-endian number, in hex.
The sipnab command opens -I files through libpcap and its archive layer. Those report problems in their own words.
This text comes from the library reader PcapReader::new or decompress_capture, and from the WebAssembly build’s file loader.
What to do: Check that the file is a .pcap or .pcapng capture (gzip compression is fine), as the message lists. Convert a file in another format first.
Exit code: None. The error goes back to the program that calls the library.
not a SIP message: first line is '{line}'
Library parser error: the first line neither starts with SIP/2.0 (a response) nor ends with SIP/2.0 (a request). So the data is not a SIP message.
{line} is that line without its leading spaces.
In the sipnab program, sipnab drops a SIP-looking packet that fails this way. It logs it only at debug level (SIPNAB_LOG=debug) as SIP parse error: followed by this text.
-x/--quiet-bad-parse silences that line.
What to do: The input is not SIP 2.0. On the command line, -x/--quiet-bad-parse hides the debug line for such packets.
Exit code: None. The error goes back to the program that calls the library.
no transport header (not UDP/TCP)
Packet decoder error from the library: the IP packet carries IGMP (multicast group management). It does not carry a transport that sipnab reads, such as UDP or TCP.
In the sipnab program this text appears only in debug logging (SIPNAB_LOG=debug). It is on a line that starts with Skipping and ends with this text.
sipnab counts the frame in the headless (-N) end-of-run NOT DECODED summary, and in the sipnab_capture_undecodable_frames_total metric. The run continues.
What to do: You need to do nothing. IGMP carries no SIP or RTP.
Exit code: None. The error goes back to the program that calls the library, and a sipnab run skips the frame and continues.
RTP version {version}, expected 2
Library parser error from parse_rtp_header. The two version bits at the start of the RTP header do not hold 2. RTP (Real-time Transport Protocol) carries call audio.
{version} is the value found.
In the sipnab program, the RTP detector treats such a UDP packet as not RTP. It drops any half-detected stream for that address pair, without printing anything.
What to do: The input is not an RTP version 2 packet. Library callers should pass only the UDP payload of an RTP packet, starting at the RTP header.
Exit code: None. The error goes back to the program that calls the library.
SDP must start with a v= line
Library parser error from parse_sdp. SDP (Session Description Protocol) is the part of a SIP message that describes the media.
The first non-blank line of the SDP body does not begin with v=. Or the body holds only blank lines.
In the sipnab program, sipnab does not use a SIP message body that fails this way for media setup. It prints no message.
What to do: The SDP body has the wrong form. It must start with a v=0 line.
Exit code: None. The error goes back to the program that calls the library.
{what} too short: {got} bytes (need {need})
Data is shorter than the structure it must hold.
{what} names the structure.
{got} is the number of bytes available.
{need} is the number of bytes required.
The meaning depends on what reports it:
The RTP parser (RTP header, RTP CSRC list, RTP extension header, RTP extension payload): the RTP detector silently treats the packet as not RTP.
The capture reader (capture file, pcap global header, pcapng section header): it comes from the library function PcapReader::new.
The packet decoder (headers such as Linux SLL packet or GRE header): sipnab counts the frame as truncated in the headless (-N) end-of-run NOT DECODED summary.
What to do: For truncated frames, capture again with a larger --snaplen. For a capture file or RTP packet, the input ends early or is not in that format.
Exit code: None. The error goes back to the program that calls the library, or sipnab counts the frame as truncated, and the run continues.
unsupported GRE inner protocol: 0x{0:04X}
Packet decoder error from the library: a GRE tunnel packet carries an inner protocol other than IPv4, IPv6 or Transparent Ethernet Bridging (0x6558).
{0} is the protocol type in hex.
In the sipnab program this text appears only in debug logging (SIPNAB_LOG=debug). It is on a line that starts with Skipping and ends with this text.
sipnab counts the frame in the headless (-N) end-of-run NOT DECODED summary, and in the sipnab_capture_undecodable_frames_total metric. The run continues.
What to do: The run needs nothing from you. sipnab does not decode traffic inside that tunnel type.
Exit code: None. The error goes back to the program that calls the library, and a sipnab run skips the frame and continues.
unsupported IP protocol number: {0}
Packet decoder error (library surface). The packet’s IP protocol number names a payload that sipnab does not read as a transport.
{0} is that number.
It occurs for:
an IP payload with no UDP, TCP or SCTP header that sipnab can slice;
ESP (protocol 50) that is not readable null-encrypted ESP;
an Authentication Header that protects something other than UDP or TCP;
a HEP-delivered packet whose stated protocol maps to no SIP transport.
In the sipnab program, this text appears only in debug logging (SIPNAB_LOG=debug) as Skipping unparseable packet: ....
sipnab counts the frame in the headless (-N) end-of-run NOT DECODED summary, and in the sipnab_capture_undecodable_frames_total metric. The run continues.
What to do: The run needs no action. The headless (-N) end-of-run summary lists the protocol numbers it skipped as no transport (IP protocol N).
Exit code: None. This is a warning, and the run continues.
unsupported link type: {0}
Packet decoder error (library surface). sipnab does not decode the capture’s link-layer header type.
The link-layer header type is the DLT number. It tells the reader how each frame starts.
{0} is that number.
sipnab supports Ethernet, Linux cooked capture v1 and v2, raw IP, PPP and BSD loopback.
In the sipnab program, every frame of such a capture fails this way.
The headless (-N) end-of-run summary reports unsupported link type <N>, and the run continues.
What to do: Capture on an interface, or with a capture tool setting, that produces one of the supported link types.
Exit code: None. This is a warning, and the run continues.
unsupported SDP version: '{version}'
Library parser error from parse_sdp. The SDP v= line gives a version other than 0.
{version} is the text after v=.
In the sipnab program, sipnab does not use a SIP message body that fails this way for media setup. It prints no message.
What to do: The sender produced a malformed SDP body. Its first line must be v=0.
Exit code: None. The error goes back to the program that calls the library.