stamparm/maltrail · error
[!] no trail set at (pass --trails)
Error message
[!] no trail set at %s (pass --trails)
What it means
refnet.py main() requires a trail set file to drive pcap generation. When not in --score mode it checks that the --trails path exists as a file; if not, it exits with this message reminding you to pass --trails. Without trails there is nothing to plant in the generated traffic, so the tool refuses to continue.
Solutions
- Pass --trails with the path to an existing trail file, e.g. --trails trails.csv
- Verify the path exists (ls the file) and that you're running from the directory your relative path assumes
- Copy or download the trail set if it lives outside this checkout
- If you meant to score a previous run instead, use --score with the run's output directory
Example fix
# before python sensor/tools/refnet.py --out /tmp/run # after python sensor/tools/refnet.py --out /tmp/run --trails trails/trails.csv
Defensive patterns
Strategy: validation
Validate before calling
import os, argparse
opts = parser.parse_args()
assert opts.trails and os.path.isfile(opts.trails), f"trail set missing at {opts.trails!r} - pass --trails" Prevention
- Always pass --trails explicitly with an absolute path
- Keep the trail set in the repo or a documented location
- Verify the file exists from the CWD you run refnet in
When it happens
Trigger: Running refnet.py (generate mode, no --score) with the --trails option pointing to a non-existent file, or relying on a default trails path that isn't present at the expected location.
Common situations: Forgot to pass --trails on the CLI; passed a relative path from the wrong working directory; trails file was deleted/moved or lives in a private feed directory not present on this machine.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- [!] version %r is not 'major.minor[.patch]'
- [x] invalid IP address
- not a Maltrail provenance sidecar (bad magic)
- provenance sidecar is truncated
- packet too short for header-protection sample
AI-assisted analysis of stamparm/maltrail@77cfb06d76 (2026-09-13).
Data as JSON: /api/errors/46e385f14348ab8a.
Report an issue: GitHub.
Appendix: source
Thrown at sensor/tools/refnet.py:264
parser.add_argument("--hosts", type=int, default=500)
parser.add_argument("--minutes", type=int, default=60)
parser.add_argument("--seed", type=int, default=1312)
parser.add_argument("--planted", type=int, default=10, help="per trail kind")
parser.add_argument("--scans", type=int, default=3)
parser.add_argument("--trails", default=os.path.expanduser("~/.maltrail/trails.csv"))
parser.add_argument("--sensor", default=None)
parser.add_argument("--generate", action="store_true", help="write the pcap and stop")
parser.add_argument("--score", metavar="DIR", help="score a directory a previous run wrote")
parser.add_argument("--min-detection", type=float, default=None, help="fail below this %%")
parser.add_argument("--max-false", type=int, default=None, help="fail above this many false positives")
options = parser.parse_args()
if options.score:
meta = json.load(io.open(os.path.join(options.score, "truth.json"), encoding="utf8"))
result = score(meta, events(os.path.join(options.score, "logs")))
else:
if not os.path.isfile(options.trails):
raise SystemExit("[!] no trail set at %s (pass --trails)" % options.trails)
pcap, meta = generate(options.out, options.hosts, options.minutes, options.seed,
options.planted, options.scans, options.trails)
print("[i] %d host(s), %d minute(s), seed %d -> %d packets (%.0f MB)"
% (meta["hosts"], meta["minutes"], meta["seed"], meta["packets"], os.path.getsize(pcap) / 1e6))
if options.generate:
return 0
logdir, elapsed = replay(pcap, options.out, options.trails, options.sensor)
print("[i] replayed in %.2fs" % elapsed)
result = score(meta, events(logdir))
print("\n[i] detection rate %5.1f%% (%d/%d planted trails)"
% (result["detection_rate"], result["detected"], result["planted"]))
print("[i] scans detected %5d/%d" % (result["scans_detected"], result["scans_planted"]))
print("[i] false positives %5d (%.2f per 100k benign packets)"
% (result["false_positives"], result["fp_per_100k_benign"]))
print("[i] events/day/1000 hosts %5.0f" % result["events_per_day_per_1000_hosts"])
if result["missed"]:
print("\n[!] missed: %s" % ", ".join("%s->%s" % _ for _ in result["missed"][:5]))View on GitHub (pinned to 77cfb06d76)