Testing a Suricata rule proves that the signature loads and matches the traffic it was written to detect. A small offline replay keeps the check repeatable, so the same rule and packet capture can be used during review, tuning, or a sensor build.
The -S option loads only the supplied test rule for the replay run, while -r reads a saved pcap file and -l writes output into a separate log directory. Keeping the test rule and replay logs outside the service directories avoids mixing lab evidence with the sensor's normal rules and alerts.
Use a capture that contains the exact traffic the rule should match. The sample rule below alerts on an HTTP request for /sample.txt and uses local sid 9000002, so the matching fast.log and eve.json entries should show that signature ID.
Related: How to add a local Suricata rule
Related: How to test Suricata with pcap replay
$ mkdir suricata-rule-test
$ cd suricata-rule-test
$ cp ~/captures/rule-test.pcap ./rule-test.pcap
The capture must contain the packet or request your rule is meant to match. For the sample rule, use a capture with an HTTP request for /sample.txt.
$ vi rule-test.rules
alert http any any -> any any (msg:"SG Suricata rule test HTTP request"; http.uri; content:"/sample.txt"; sid:9000002; rev:1;)
Use a local sid range reserved for your environment. Reusing a managed rule sid can make suppression, thresholding, and alert triage point at the wrong signature.
$ suricata -T -c /etc/suricata/suricata.yaml -S rule-test.rules -v Notice: suricata: This is Suricata version 8.0.3 RELEASE running in SYSTEM mode Info: suricata: Running suricata under test mode Info: detect: 1 rule files processed. 1 rules successfully loaded, 0 rules failed, 0 rules skipped Notice: suricata: Configuration provided was successfully loaded. Exiting.
-S loads this rule file exclusively for the test, so the rule count should match the test file instead of the full production ruleset.
Related: How to test Suricata configuration
$ mkdir rule-test-logs
$ suricata -r rule-test.pcap -l rule-test-logs -S rule-test.rules -k none i: suricata: This is Suricata version 8.0.3 RELEASE running in USER mode i: threads: Threads created -> RX: 1 W: 8 FM: 1 FR: 1 Engine started. i: suricata: Signal Received. Stopping engine. i: pcap: read 1 file, 9 packets, 688 bytes
-k none disables checksum validation for the replay, which avoids false misses when the capture came from a host using checksum offload. Leave checksum validation enabled when checksum correctness is part of the rule test.
$ ls rule-test-logs eve.json fast.log stats.log suricata.log
$ cat rule-test-logs/fast.log
06/25/2026-08:10:00.000000 [**] [1:9000002:1] SG Suricata rule test HTTP request [**] [Classification: (null)] [Priority: 3] {TCP} 192.0.2.10:49152 -> 192.0.2.20:80
The bracketed alert ID should show the local sid and revision from rule-test.rules.
Related: How to view Suricata alert logs
$ jq -r 'select(.event_type=="alert") | [.alert.signature_id, .alert.signature, .src_ip, .dest_ip, .proto] | @tsv' rule-test-logs/eve.json 9000002 SG Suricata rule test HTTP request 192.0.2.10 192.0.2.20 TCP
Matching fast.log and eve.json output confirms that the replay reached detection and both alert outputs.
Related: How to read Suricata eve.json logs
$ rm -rf rule-test-logs rule-test.rules rule-test.pcap
Run the cleanup from the lab directory only. The command removes the copied pcap, the one-rule test file, and the replay logs in the current directory.