Simulation Placeholders
A template is a block of text whose {{name}} slots are filled in afresh for every record it produces. Each slot is a placeholder: a typed instruction such as "an address from this range", "one of these three words", "a timestamp in syslog format".
Templates are written in two places, and both use the placeholders described here:
- On a device, under Device Simulation, in the
Template field and thePlaceholders editor. - In the Library, under Library: Samples, on a sample of type
Template .
Everything on this page is the same on both surfaces.
Writing a Template
Every non-empty line of a template is one candidate record. A template of four lines produces four different records, cycling through them in order or picking at random — see Device Simulation for the
<134>{{ts}} fw-edge-01 vmfw: action=allow src={{src_ip}}:{{src_port}} dst={{dst_ip}}:443 user={{username}}
<134>{{ts}} fw-edge-01 vmfw: action=deny src={{src_ip}}:{{src_port}} dst={{dst_ip}}:22 user={{username}}
Two rules decide what a {{name}} does, and both catch people out.
Any Type Name Works on Its Own
A {{name}} that is itself the name of a placeholder type needs no definition. Writing {{ip}}, {{email}} or {{http_status}} produces an address, an e-mail address and an HTTP status code using that type's defaults, with nothing added to the
The one exception is {{choice}}. A choice has no values to choose from until you declare them, so a bare {{choice}} is rejected like any other name that was never defined.
Every name that is not a type name has to be declared. {{src_ip}} is not a type, so it needs a src_ip — and a typo such as {{src_pi}} is refused when you save, rather than appearing in the output as the literal text {{src_pi}}.
Declaring a placeholder under a type's own name overrides that type's defaults. An entry named ip with a range of 203.0.113.0/24 makes every bare {{ip}} in the template draw from that range instead.
A Placeholder Is Filled Once per Record
Each name is evaluated once per record and the same value is used everywhere it appears on that line. Writing {{src_ip}} twice yields the same address both times, which is what lets a record mention the same host in two fields and stay consistent.
Two different values on one record therefore need two names:
connection from {{src_ip}} to {{dst_ip}}
This applies per record, not for the life of the device: the next record draws fresh values for both.
Placeholder Types
Twenty types are available. The {{name}} and what appears in a device's configuration.
| Label | Type | Options it reads | Produces |
|---|---|---|---|
ip | range, unique | An IPv4 address from the range | |
int | min, max, range, unique | A whole number | |
port | min, max, range, unique | A port number | |
float | min, max, precision | A decimal number | |
choice | values, weights | One of the values you list | |
timestamp | format | The current time, formatted | |
uuid | - | A version 4 UUID | |
hex | length | Lower-case hexadecimal digits | |
string | length | Letters and digits | |
mac | - | A locally administered unicast MAC address | |
sequence | start, step | A counter that advances every record | |
username | - | A user name from a built-in list | |
hostname | - | A host name from a built-in list | |
domain | - | A domain name from a built-in list | |
email | - | An address from a built-in list | |
user_agent | - | A browser or client user-agent string | |
http_method | - | GET, POST, PUT, DELETE, HEAD, OPTIONS or PATCH | |
http_status | - | A status code such as 200, 404 or 503 | |
url_path | - | A request path from a built-in list | |
country | - | A two-letter country code |
The placeholder editor shows only the options the selected type reads. An option a type does not read is ignored.
A few alternative spellings are accepted wherever a type name is: ipv4, ipaddress and ip_address for ip; integer and number for int; enum, oneof and list for choice; time, datetime and date for timestamp; guid for uuid; seq and counter for sequence; useragent for user_agent; user and account for username; and host for hostname.
Options
| Option | Label | Applies to | Default | Description |
|---|---|---|---|---|
range | ip, int, port | - | On an ip, first and last address as 203.0.113.10-203.0.113.250, or a CIDR block such as 203.0.113.0/24; a single address is also accepted. Required unless the placeholder is a bare {{ip}}, which uses 10.0.0.0-10.255.255.255. IPv4 only. On an int or a port, min-max as a single value — a shorthand for the two fields below. A min or a max set alongside it replaces that one bound and leaves the other as the range gave it; a bound left unset keeps the range's. The placeholder editor offers | |
min | int, port, float | 0 for int, 1 for port, 0 for float | Lowest value, inclusive | |
max | int, port, float | 2147483647 for int, 65535 for port, 1 for float | Highest value, inclusive. A maximum below the minimum is refused | |
precision | float | 2 | Digits after the decimal point, at most 9 | |
values | choice | - | Comma-separated list to pick from. At least one, at most 1000 | |
weights | choice | - | One positive weight per value, in the same order. Leaving it empty picks evenly. A weight that is missing, zero or negative is refused rather than ignored | |
format | timestamp | rfc3339 | See Timestamp Formats | |
length | hex, string | 16 for hex, 8 for string | Number of characters, between 1 and 1024 | |
start | sequence | 1 | First value of the sequence | |
step | sequence | 1 | Added after every record | |
unique | ip, int, port | Off | Walk the whole range without repeating a value before starting over. The range may span at most about a trillion values, which covers any IPv4 range |
A placeholder name may contain letters, digits and underscores, and may not start with a digit. Names are case-sensitive and each has to be unique within the template.
Built-in Value Lists
username, hostname, domain, email, user_agent, http_method, http_status, url_path and country draw from lists that ship with the product and take no options. The lists are weighted towards what real traffic looks like rather than picking evenly, so GET is far more common than DELETE and 200 far more common than 503. Use choice instead when you need your own values.
Timestamp Formats
A timestamp placeholder renders the moment the record is generated. Mon Jan 2 15:04:05 MST 2006.
| Format | Renders as |
|---|---|
rfc3339 | 2026-09-19T14:32:07Z |
rfc3339nano | 2026-09-19T14:32:07.123456789Z |
iso8601 | 2026-09-19T14:32:07.123Z |
syslog | Sep 19 14:32:07 |
cef | Sep 19 2026 14:32:07 |
http | 19/Sep/2026:14:32:07 +0000 |
windows | 2026-09-19 14:32:07 |
epoch | 1789828327 |
epoch_ms | 1789828327123 |
epoch_ns | 1789828327123456789 |
The three epoch formats differ only in scale: epoch counts seconds, epoch_ms milliseconds and epoch_ns nanoseconds. A record carrying a value on the wrong scale is still a valid number, so nothing is rejected — the records simply arrive dated near 1970, or centuries into the future, and the mistake only shows up once you look at the timestamps downstream. Match the scale to what the receiving system expects.
The epoch_ns is accepted as well, and so are the spellings unix, unix_ms, epochms, unix_ns and epochns.
Timestamps always render in UTC.
Limits
| Limit | Value |
|---|---|
| Placeholders per template | 64 |
| Lines per template | 1000 |
| Characters per template line | 65536 |
Values in one choice | 1000 |
A template that exceeds any of these is refused when you save it.
Errors
A template and its placeholders are checked when you save, so a problem is reported there rather than when the device starts.
| Message | Cause |
|---|---|
simulation: template has no non-empty lines | The template is empty or contains only blank lines |
simulation: template has too many lines | More than 1000 non-empty lines |
simulation: template line is too long | A single line longer than 65536 characters |
simulation: too many placeholders | More than 64 placeholders in play, declared and bare types together |
simulation: unknown placeholder | The template references a name that is neither declared nor a type name. Every offending name is listed |
simulation: invalid placeholder name | A name using characters other than letters, digits and underscores, or starting with a digit |
simulation: duplicate placeholder name | Two entries share a name |
simulation: invalid placeholder type | A type that does not exist, or a placeholder saved with no type |
simulation: invalid range | A range that cannot be read, an end before its start, an IPv6 address, a maximum below its minimum, or a choice with more than 1000 values |
simulation: choice needs at least one value | A choice with an empty |
simulation: weights must be positive and match values | The weights are a different length to the values, or one of them is not a positive number |
simulation: range too large for unique values | |
simulation: length out of range | A hex or string length outside 1 to 1024 |