DnsStream supports three output DNS message formats controlled by the message-format directive in dnsstream.conf:
| Format | Description |
|---|---|
querylog |
ISC BIND querylog style messages delivered inside a BSD syslog or RFC 5424 syslog envelope over TCP or TLS. |
json |
Structured newline-delimited JSON (NDJSON) messages over TCP or TLS. |
dnstap |
Native dnstap messages delivered over Frame Streams (fstrm) over TCP or TLS. |
DnsStream uses dnstap as its internal message representation. Windows ETW events are converted into equivalent dnstap message types before entering the processing pipeline. dnstap messages received from UNIX domain sockets are accepted and queued unchanged.
When message-format dnstap is configured, DnsStream forwards dnstap messages without modification. Any dnstap message type can be accepted and forwarded.
DnsStream’s querylog output is based on the ISC BIND query log format, extended with a response: keyword and inline answer records for response messages. Additionally errors: to report errors relating to processing DNS messages, are also emitted.
| Channel | Message types |
|---|---|
queries |
Both query and response type events |
errors |
DNS message processing error - e.g. parse failures when trying to reformat a message |
Querylog messages are delivered as the syslog message body in both BSD syslog and RFC 5424 delivery modes.
The querylog format has two variants controlled by message-querylog-format in dnsstream.conf:
Both standard and extended formats are documented for each relevant event type.
DnsStream generates querylog output from the following dnstap message types:
AUTH_QUERYAUTH_RESPONSECLIENT_QUERYCLIENT_RESPONSERESOLVER_QUERYRESOLVER_RESPONSEFORWARDER_QUERYFORWARDER_RESPONSESTUB_QUERYSTUB_RESPONSETOOL_QUERYTOOL_RESPONSEEach message type uses the same query and response schemas documented below, with the DNS role appearing in the querylog messages adjusted for the dnstap message type (i.e. queries: client vs queries: resolver):
| dnstap type | role |
|---|---|
| AUTH_* | client |
| CLIENT_* | client |
| RESOLVER_* | resolver |
| FORWARDER_* | forwarder |
| STUB_* | stub |
| TOOL_* | tool |
All other dnstap message types are discarded when generating querylog output.
DnsStream delivers messages wrapped in a syslog envelope when message-format querylog is set. Two envelope formats are available: BSD syslog (RFC 3164) and structured syslog (RFC 5424).
The BSD syslog (RFC 3164) envelope is the older of the two formats and is supported by virtually every syslog receiver. It has no version field, uses a locale-dependent timestamp with no year or timezone, and carries the PID in bracket notation attached to the app name.
<30>Mar 23 19:40:44 WIN-4L04FD5AKGL dnsstream[8296]: <message>
| Field | Example | Description |
|---|---|---|
priority |
<30> |
Syslog priority encoded as <facility × 8 + severity>. <30> = facility 3 (daemon) + severity 6 (informational). |
timestamp |
Mar 23 19:40:44 |
Local server time in MMM DD HH:MM:SS format. No year, no timezone designator. |
hostname |
WIN-4L04FD5AKGL |
Hostname of the DNS server. |
app-name |
dnsstream |
Always dnsstream. |
procid |
[8296] |
Process ID of the DnsStream service, in brackets immediately after the app name, followed by a colon. |
message |
- | The <message> payload. Begins immediately after the colon and space. |
The BSD syslog timestamp has no year and no timezone. On DNS servers that span multiple timezones, or where log correlation depends on sub-second precision, prefer RFC 5424.
RFC 5424 is the modern structured syslog format. It adds a version field, a timezone-aware ISO 8601 timestamp, a message ID field, and a structured data section. DnsStream sets both the message ID and structured data fields to the nil value -, carrying all message data in the message body.
<30>1 2000-01-01T19:00:00.23123Z windows2025 dnsstream 6824 - - <message>
| Field | Example | Description |
|---|---|---|
priority |
<30> |
Syslog priority. Same encoding as BSD syslog. |
version |
1 |
RFC 5424 version. Always 1. No separator between priority and version. |
timestamp |
2000-01-01T19:00:00.23123Z |
ISO 8601 / RFC 3339 timestamp in UTC including nanoseconds. Year and timezone are always present. Z suffix denotes UTC. |
hostname |
windows2025 |
Hostname of the DNS server. |
app-name |
dnsstream |
Always dnsstream. |
procid |
6824 |
Process ID of the DnsStream service. Space-separated, no brackets. |
msgid |
- |
Nil. DnsStream does not populate the RFC 5424 message ID field. |
structured-data |
- |
Nil. All message data is in the message body. |
message |
- | The <message> payload. Begins after the final - and space. |
Prefer RFC 5424 (rfc5424) for all new deployments. The timezone-aware timestamp eliminates ambiguity in multi-timezone environments, and the version field makes the format reliably distinguishable from other syslog sources in mixed-origin pipelines.
The same priority value, which defaults to <30>, is used for all DnsStream messages. For reference:
| Facility | Value | Severity | Value | Combined priority |
|---|---|---|---|---|
| daemon | 3 | informational | 6 | <30> |
This can changed in the dnsstream.conf configuration file using the message-syslog-priority directive.
The query schema is used for:
AUTH_QUERYCLIENT_QUERYRESOLVER_QUERYFORWARDER_QUERYSTUB_QUERYTOOL_QUERYThe only difference is the role keyword immediately following queries:.
Full message - with message-syslog-format rfc5424 and message-querylog-format standard set:
<30>1 2000-01-01T19:00:00.23123Z windows2025 dnsstream 6824 - - queries: client 192.168.68.164#61776: query: telemity.com. IN A + (192.168.68.162)
Full message - with message-syslog-format rfc5424 and message-querylog-format extended set:
<30>1 2000-01-01T19:00:00.23123Z windows2025 dnsstream 6824 - - queries: resolver 192.168.68.164#61776 %1085: query: telemity.com. [telemity.com.] IN A + (192.168.68.162 32b)
Full message - with message-syslog-format bsd and message-querylog-format standard set:
<30>Mar 23 19:40:44 WIN-4L04FD5AKGL dnsstream[8296]: queries: forwarder 192.168.68.164#61750: query: telemity.com. IN A + (192.168.68.162)
Standard fields are always included, extended fields are only present when message-querylog-format extended is set.
| Field | Example | Format | Description |
|---|---|---|---|
message-keyword |
queries: |
Standard | Fixed keyword present on all DnsStream querylog messages. |
role-keyword |
client, resolver, forwarder, stub or tool |
Standard | Role derived from the dnstap message type. |
client-ip |
192.168.68.164 |
Standard | IPv4 or IPv6 address of the DNS client. |
client-port |
#61776 |
Standard | Source port of the query, separated from the client IP by #. |
txid |
%1085 |
Extended | DNS transaction ID. 16-bit value shared between the query and its response. Identifiable with its % prefix. |
type-keyword |
query: |
Standard | Identifies this as a client query message. Response messages use response: here. |
qname |
telemity.com. |
Standard | Queried domain name, always with a trailing dot unless message-fqdn-format without-trailing-dot is set. |
qdomain |
[telemity.com.] |
Extended | The DNS domain derived from the query name. For example, a query for www.sub.telemity.com. yields [telemity.com.]. If domain-suffix-mode off is set, this field will be empty, i.e. []. |
qclass |
IN |
Standard | DNS query class. IN in all normal deployments. |
qtype |
A |
Standard | DNS record type requested. |
flags |
+ |
Standard | Query flags. See below. |
server-ip |
(192.168.68.162) or (<unknown>) |
Standard | IP address of the DNS server interface that received the query. If unavailable in the dnstap message, <unknown> is emitted. |
size |
(192.168.68.162 117b) |
Extended | Size of the DNS response packet in bytes. Inserted into the brackets containing the server IP with a space between the two fields. Easily identifiable with its b suffix. |
The flags object reflects the DNS header flags present in the query. Flags are concatenated without separators. The following flags are currently included:
| Character | Flag | Meaning |
|---|---|---|
+ |
RD - Recursion Desired | Client requested recursive resolution, if not field will be set to -. This flag is always present. |
T |
TCP | Query arrived over TCP rather than UDP, otherwise not present. |
The response schema is used for:
AUTH_RESPONSECLIENT_RESPONSERESOLVER_RESPONSEFORWARDER_RESPONSESTUB_RESPONSETOOL_RESPONSEThe only difference is the role keyword immediately following queries:.
Full message - with message-syslog-format rfc5424 and message-querylog-format standard set:
<30>1 2000-01-01T19:00:00.23123Z windows2025 dnsstream 6824 - - queries: client 192.168.68.164#61776: response: www.telemity.com. IN A + (192.168.68.162) NOERROR; www.telemity.com. 600 IN CNAME telemity.com.; telemity.com. 600 IN A 20.47.114.0
Full message - with message-syslog-format rfc5424 and message-querylog-format extended set:
<30>1 2000-01-01T19:00:00.23123Z windows2025 dnsstream 6824 - - queries: resolver 192.168.68.164#61776 %1085: response: www.telemity.com. [telemity.com.] IN A + (192.168.68.162 89b) NOERROR; www.telemity.com. [telemity.com.] 600 IN CNAME telemity.com.; telemity.com. [telemity.com.] 600 IN A 20.47.114.0
Full message - with message-syslog-format bsd and message-querylog-format standard set:
<30>Mar 23 19:40:44 WIN-4L04FD5AKGL dnsstream[8296]: queries: forwarder 192.168.68.164#61776: response: www.telemity.com. IN A + (192.168.68.162) NOERROR; www.telemity.com. 600 IN CNAME telemity.com.; telemity.com. 600 IN A 20.47.114.0
Standard fields are always included, extended fields are only present when message-querylog-format extended is set.
| Field | Example | Format | Description |
|---|---|---|---|
message-keyword |
queries: |
Standard | Fixed keyword. Same as client query. |
role-keyword |
client, resolver, forwarder, stub or tool |
Standard | Role derived from the dnstap message type. |
client-ip |
192.168.68.164 |
Standard | IPv4 or IPv6 address of the DNS client. |
client-port |
#61776 |
Standard | Source port of the query. |
txid |
%1085 |
Extended | DNS transaction ID. 16-bit value shared between the query and its response. Identifiable with its % prefix. |
type-keyword |
response: |
Standard | Distinguishes this as a client response message. Query messages use query: here. |
qname |
www.telemity.com. |
Standard | Queried domain name, always with a trailing dot unless message-fqdn-format without-trailing-dot is set. The name from the original question - not necessarily the name in the answer records. |
qdomain |
[telemity.com.] |
Extended | The DNS domain derived from the query name. For example, a query for www.sub.telemity.com. yields [telemity.com.]. If domain-suffix-mode off is set, this field will be empty, i.e. []. |
qclass |
IN |
Standard | DNS query class. |
qtype |
A |
Standard | DNS record type that was requested. |
flags |
+ |
Standard | Query flags from the original request. See below. |
server-ip |
(192.168.68.162) or (<unknown>) |
Standard | DNS server interface that received the query. If unavailable in the dnstap message, <unknown> is emitted. |
size |
(192.168.68.162 117b) |
Extended | Size of the DNS response packet in bytes. Inserted into the brackets containing the server IP with a space between the two fields. Easily identifiable with its b suffix. |
rcode |
NOERROR |
Standard | DNS response code in string form. |
answer-records |
; <record>; <record> ... |
Standard | Answer section records in DNS presentation format, each preceeded by ; . No trailing semicolon. FQDNs in record name and data fields always end with a trailing dot unless message-fqdn-format without-trailing-dot is set. |
The flags object reflects the DNS header flags present in the response. Flags are concatenated without separators. The following flags are currently included:
| Character | Flag | Meaning |
|---|---|---|
+ |
RD - Recursion Desired | Client requested recursive resolution, if not field will be set to -. This flag is always present. |
T |
TCP | Query arrived over TCP rather than UDP, otherwise not present. |
Each record in the answer-record field follows standard DNS presentation format: name ttl class type data. For extended querylog format, an additional domain field is present after name. All records are preceeded with ; (semicolon and space) which allows parsing using regex groupings and determining the presence of answer records easier. The example shows a two-record CNAME chain in extended format:
; www.telemity.com. [telemity.com.] 600 IN CNAME telemity.com.; telemity.com. [telemity.com.] 600 IN A 20.47.114.0
| Sub-field | Example | Format | Description |
|---|---|---|---|
name |
www.telemity.com. |
Standard | Owner name of the record, with trailing dot. Differs from qname on intermediate CNAME records. |
domain |
[telemity.com.] |
Extended | The DNS domain derived from the name of the record. For example, a record name www.sub.telemity.com. yields [telemity.com.]. If domain-suffix-mode off is set, this field will be empty, i.e. []. |
ttl |
600 |
Standard | Time to live in seconds. |
class |
IN |
Standard | Record class. Always IN. |
type |
CNAME / A |
Standard | Record type. May differ from qtype in CNAME chains. |
data |
telemity.com. / 20.47.114.0 |
Standard | Record data in presentation format. Format is type-dependent. |
FQDNs in name and data always end with a trailing dot unless message-fqdn-format without-trailing-dot is set.
The data field of each DNS record is always a string in DNS presentation format, i.e. what you might find in a DNS zone file in plain text format. The format is determined by rrtype, e.g..
rrtype |
Format | Example |
|---|---|---|
A |
IPv4 address | "20.47.114.0" |
AAAA |
IPv6 address | "2606:2800:220:1:248:1893:25c8:1946" |
CNAME |
Domain name | "telemity.com." |
MX |
Preference and exchange name | "10 mail.telemity.com." |
NS |
Name server name | "ns1.telemity.com." |
PTR |
Domain name | "telemity.com." |
TXT |
Quoted string | "\"v=spf1 include:_spf.google.com ~all\"" |
SOA |
mname rname serial refresh retry expire minimum | "ns1.telemity.com. hostmaster.telemity.com. 2024031201 3600 900 604800 300" |
SRV |
Priority weight port target | "10 20 443 sip.telemity.com." |
| Unknown | Hex-encoded data with length prefix | "\# 32 0004e01a..." |
Unknown record types are preserved as hex-encoded data and are never silently dropped. If DnsStream encounters an unfamiliar rrtype, the raw bytes are always available in data using the format \# <length> <hex-encoding>.
Generated when DnsStream receives a message which contains a DNS packet it cannot parse. Captures the raw packet for downstream analysis and includes an error description.
Error messages are delivered to the same forwarding target as DNS messages, in the same querylog format. This is embedded in the same configured Syslog envelope, and can be parsed and routed by the same pipeline. It is distinguished from other message by the errors: keyword in place of queries:.
Full message - with message-syslog-format rfc5424 set:
<28>1 2000-01-01T19:00:00.23123Z windows2025 dnsstream 6824 - - errors: Read DNS message failed: Read uint16_t failed: Offset 8 + 2 is out of bounds for data of 9 bytes: client 192.168.68.164#54812: server 192.168.68.100: packet \# 9 A51500200001000000
Full message - with message-syslog-format bsd set:
<28>Mar 23 19:40:44 WIN-4L04FD5AKGL dnsstream[8296]: errors: Read DNS message failed: Read uint16_t failed: Offset 8 + 2 is out of bounds for data of 9 bytes: client 192.168.68.164#54812: server 192.168.68.100: packet \# 9 A51500200001000000
| Field | Example | Description |
|---|---|---|
message-keyword |
errors: |
Fixed keyword identifying this as an error message. Distinct from the queries: keyword used on query and response messages. |
error-text |
Read DNS message failed: ... |
Human-readable error description from the DNS Server service explaining why the packet could not be parsed. |
client-keyword |
client |
Fixed keyword preceding the client address. |
client-ip |
192.168.68.164 |
IPv4 or IPv6 address of the client relating to the malformed packet (this may be the sender or the receiver of it). |
client-port |
#54812 |
Source port of the malformed packet, separated from the client IP by #. |
server-keyword |
server |
Fixed keyword preceding the client address. |
server-ip |
192.168.68.100 |
IPv4 or IPv6 address of the server relating to the malformed packet (this may be the sender or the receiver of it) |
packet-keyword |
packer |
Fixed keyword preceding the packet data. |
packet-data |
\# 9 A515002000010000001b2c3d4e5f0a1b2c |
Hex-encoded bytes of the raw packet as received with a length prefix. Suitable for offline analysis. |
DnsStream’s JSON output sends newline-delimited JSON objects (NDJSON) over a persistent TCP connection. Each message is a single JSON object on a single line, terminated by \n. There is no framing, no length prefix, and no enclosing array - each line is a complete, independently parseable message.
{"timestamp":"2000-01-01T19:00:00.23123Z","host":"windows2025",...}\n
Every DnsStream JSON message shares the same top-level structure.
{
"timestamp": "2000-01-01T19:00:00.23123Z",
"host": "windows2025",
"schema": 1,
"type": "client-response",
"data": { ... }
}
| Field | Type | Example | Description |
|---|---|---|---|
timestamp |
string | "2000-01-01T19:00:00.23123Z" |
ISO 8601 / RFC 3339 capture timestamp in UTC including nanoseconds. Z suffix always present. |
host |
string | "windows2025" |
NetBIOS name or FQDN of the DNS server, or the value of message-hostname if set. |
schema |
integer | 1 |
Message schema version, currently always 1. |
type |
string | "client-response" |
Message type discriminator. See message types below. |
data |
object | - | DNS message payload. Structure varies by type. |
The following message types are currently defined for JSON output:
client-queryclient-responseresolver-queryresolver-responseforwarder-queryforwarder-responsestub-querystub-responsetool-querytool-responseinvalid-messageAll query and response message types share the same schemas as client-query and client-response.
All other dnstap message types are discarded when generating JSON output.
Generated for DNS query messages. Contains question section fields only - no response data is present.
This schema is used for:
client-queryresolver-queryforwarder-querystub-querytool-queryOnly the top-level type field differs.
{
"timestamp": "2000-01-01T19:00:00.23123Z",
"host": "windows2025",
"schema": 1,
"type": "client-query",
"data": {
"client": "192.168.68.164",
"server": "192.168.68.162",
"port": 61776,
"proto": "UDP",
"size": 32,
"txid": 1085,
"flags": {
"rd": true
},
"qname": "www.telemity.com.",
"qdomain": "telemity.com.",
"qclass": "IN",
"qtype": "A"
}
}
The following data fields are included in addition to the Top-level envelope fields:
| Field | Type | Example | Description |
|---|---|---|---|
client |
string | "192.168.68.164" |
IPv4 or IPv6 address of the DNS client that sent the query. |
server |
string | "192.168.68.162" or "" |
IP address of the DNS server interface that received the query. If unavailable in the dnstap message, an empty field is emitted. |
port |
integer | 61776 |
Source port of the query on the client side. |
proto |
string | "UDP" |
Transport protocol. E.g. "UDP" or "TCP". |
size |
integer | 32 |
Size of the DNS query packet in bytes. |
txid |
integer | 1085 |
DNS transaction ID. 16-bit value chosen by the client and echoed in the server’s response. Use this field to correlate a client-query with its corresponding client-response. |
flags |
object | See below | Flags from the DNS message header, see below. |
qname |
string | "www.telemity.com." |
Queried domain name. Trailing dot present unless message-fqdn-format without-trailing-dot is set in dnsstream.conf. |
qdomain |
string | "telemity.com." |
Registered apex domain derived from qname. A query for www.sub.telemity.com. yields "telemity.com.". Absent if domain-suffix-mode off is set. |
qclass |
string | "IN" |
DNS query class. "IN" (Internet) in all normal deployments. |
qtype |
string | "A" |
DNS record type requested by the client. Common values: "A", "AAAA", "CNAME", "MX", "TXT", "NS", "PTR", "SOA", "SRV". |
The flags object reflects the DNS header flags present in the query.
| Field | Type | Example | Description |
|---|---|---|---|
rd |
boolean | true |
Recursion Desired. Client requests that the server resolve the query recursively. |
Generated for DNS response messages. Extends query fields with the server’s answer - the response code and the full answer, authority, and additional sections.
This schema is used for:
client-responseresolver-responseforwarder-responsestub-responsetool-responseOnly the top-level type field differs.
{
"timestamp": "2000-01-01T19:00:00.23123Z",
"host": "windows2025",
"schema": 1,
"type": "client-response",
"data": {
"client": "192.168.68.164",
"server": "192.168.68.162",
"port": 61776,
"proto": "UDP",
"size": 89,
"txid": 1085,
"flags": {
"rd": true,
"ra": true,
"aa": false,
"tc": false
},
"qname": "www.telemity.com.",
"qdomain": "telemity.com.",
"qclass": "IN",
"qtype": "A",
"rcode": "NOERROR",
"answers": [
{
"name": "www.telemity.com.",
"domain": "telemity.com.",
"ttl": 600,
"rrclass": "IN",
"rrtype": "CNAME",
"data": "telemity.com."
},
{
"name": "telemity.com.",
"domain": "telemity.com.",
"ttl": 600,
"rrclass": "IN",
"rrtype": "A",
"data": "20.47.114.0"
}
],
"authority": [],
"additional": []
}
}
The following data fields are included in addition to the Top-level envelope fields:
| Field | Type | Example | Description |
|---|---|---|---|
client |
string | "192.168.68.164" |
IPv4 or IPv6 address of the DNS client. |
server |
string | "192.168.68.162" or "" |
IP address of the DNS server interface that received the query. If unavailable in the dnstap message, an empty field is emitted. |
port |
integer | 61776 |
Source port of the original query on the client side. |
proto |
string | "UDP" |
Transport protocol. E.g. "UDP" or "TCP". |
size |
integer | 89 |
Size of the DNS response packet in bytes. |
txid |
integer | 1085 |
DNS transaction ID. Matches the txid on the corresponding client-query message. |
flags |
object | See below | Flags from the DNS message header, see below. |
qname |
string | "www.telemity.com." |
The name from the original question section - not necessarily the name that appears in the answer records. Trailing dot present unless message-fqdn-format without-trailing-dot is set in dnsstream.conf. |
qdomain |
string | "telemity.com." |
Registered apex domain derived from qname. A query for www.sub.telemity.com. yields "telemity.com.". Absent if domain-suffix-mode off is set. |
qclass |
string | "IN" |
DNS query class. |
qtype |
string | "A" |
DNS record type that was requested. The answer section may contain records of a different type - for example CNAME records before the terminal address record. |
rcode |
string | "NOERROR" |
DNS response code. |
answers |
array | See below | DNS answer section records. An array of DNS records as defined below. |
authority |
array | See below | DNS authority section records. An array of DNS records as defined below. |
additional |
array | See below | DNS additional section records. An array of DNS records as defined below. |
The flags object reflects the DNS header flags present in the response.
| Field | Type | Example | Description |
|---|---|---|---|
rd |
boolean | true |
Recursion Desired. Client requests that the server resolve the query recursively. |
ra |
boolean | false |
Recursion Available. Always false on client query messages - this flag is set by the server in its response. |
aa |
boolean | false |
Authoritative Answer. Always false on client query messages. |
tc |
boolean | false |
Truncated. true if the response packet was truncated. |
DNS records in answers, authority, and additional are objects which define one complete DNS record:
| Field | Type | Description |
|---|---|---|
name |
string | Owner name of the record. Differs from qname on intermediate CNAME records. Trailing dot present unless message-fqdn-format without-trailing-dot is set in dnsstream.conf. |
domain |
string | Registered apex domain derived from name. A name of www.sub.telemity.com. yields "telemity.com.". Absent if domain-suffix-mode off is set. |
ttl |
integer | Time to live in seconds. |
rrclass |
string | Resource record class. Always "IN" in practice. |
rrtype |
string | Resource record type. Determines the format of data. |
data |
string | Record data in DNS presentation format. |
Trailing dots on domain names are present unless message-fqdn-format without-trailing-dot is set in dnsstream.conf, in which case they are omitted from all FQDN values throughout the message.
The data field of each DNS record is always a string in DNS presentation format, i.e. what you might find in a DNS zone file in plain text format. The format is determined by rrtype, e.g..
rrtype |
Format | Example |
|---|---|---|
A |
IPv4 address | "20.47.114.0" |
AAAA |
IPv6 address | "2606:2800:220:1:248:1893:25c8:1946" |
CNAME |
Domain name | "telemity.com." |
MX |
Preference and exchange name | "10 mail.telemity.com." |
NS |
Name server name | "ns1.telemity.com." |
PTR |
Domain name | "telemity.com." |
TXT |
Quoted string | "\"v=spf1 include:_spf.google.com ~all\"" |
SOA |
mname rname serial refresh retry expire minimum | "ns1.telemity.com. hostmaster.telemity.com. 2024031201 3600 900 604800 300" |
SRV |
Priority weight port target | "10 20 443 sip.telemity.com." |
| Unknown | Hex-encoded data with length prefix | "\# 32 0004e01a..." |
Unknown record types are preserved as hex-encoded data and are never silently dropped. If DnsStream encounters an unfamiliar rrtype, the raw bytes are always available in data using the format \# <length> <hex-encoding>.
Generated when DnsStream receives a message which contains a DNS packet it cannot parse. Captures the raw packet for downstream analysis and includes an error description.
{
"timestamp": "2000-01-01T19:00:00.23123Z",
"host": "windows2025",
"schema": 1,
"type": "error",
"data": {
"client": "192.168.68.164",
"server": "192.168.68.162",
"port": 54812,
"size": 9,
"text": "Read DNS message failed: Read uint16_t failed: Offset 8 + 2 is out of bounds for data of 9 bytes",
"packet": "0a1b2c3d4e5f0a1b2c"
}
}
The following data fields are included in addition to the Top-level envelope fields:
| Field | Type | Example | Description |
|---|---|---|---|
client |
string | "192.168.68.164" |
IPv4 or IPv6 address of the client relating to the malformed packet (this may be the sender or the receiver of it). |
server |
string | "192.168.68.162" |
IPv4 or IPv6 address of the server relating to the malformed packet (this may be the sender or the receiver of it). |
port |
integer | 54812 |
Source port of the packet on the client side. |
size |
integer | 18 |
Size of the received packet in bytes. |
text |
string | "Read DNS message failed..." |
Error describing why the packet could not be parsed. |
packet |
string | "0a1b2c3d4e5f0a1b2c" |
Hex-encoded bytes of the raw packet as received. Suitable for offline analysis. |
When message-format dnstap is set, DnsStream emits dnstap messages over Frame Streams (fstrm) using TCP or TLS transport. DnsStream uses dnstap as its internal message representation.
For Linux, inbound dnstap messages are accepted and forwarded unchanged.
For Windows, ETW events are converted into dnstap messages before entering the processing pipeline and are then forwarded as dnstap messages.
| Windows ETW event | dnstap message type |
|---|---|
QUERY_RECEIVED |
CLIENT_QUERY |
RESPONSE_SUCCESS |
CLIENT_RESPONSE |
RESPONSE_FAILURE |
CLIENT_RESPONSE |
RECURSE_QUERY_OUT |
RESOLVER_QUERY |
RECURSE_RESPONSE_IN |
RESOLVER_RESPONSE |
The ETW client query message, ETW client response message, ETW resolver query message and ETW resolver response message sections identify how the ETW event fields are mapped to dnstap message fields.
Error messages are not emitted as dnstap messages as dnstap does not contain provisions for these, additionally for dnstap, messages are not parsed so the error messages are not generated.
Forwarded dnstap messages are transported using Frame Streams (fstrm) over plaintext TCP or TLS-encrypted TCP. The transport is configured using the standard forwarder directive and optional TLS parameters in dnsstream.conf.
DnsStream supports both fstrm modes:
| Mode | Description |
|---|---|
bidirectional |
Standard bidirectional fstrm negotiation mode. Recommended for most deployments and the default. On connect performs a handshake before sending data using a READY, ACCEPT and START sequence, and a STOP and FINISH finish sequence when the connection is gracefully closed. |
unidirectional |
Sends dnstap frames without bidirectional negotiation for compatibility with collectors expecting unidirectional streams. On connect simply emits a START control frame before sending data, and a STOP when the connection is gracefully closed. |
The mode is controlled by fstrm-mode option on the forwarder directive, the default should suffice unless there is a specific requirement for unidirectional.
For dnstap messages created from Windows ETW events, when converting to dnstap DnsStream optionally populates the dnstap identity, version and extra fields using options on the listener etw directive.
| Field | Controlled by | Default |
|---|---|---|
identity |
dnstap-identity |
Value derived from message-hostname |
version |
dnstap-version |
Omitted |
extra |
dnsta-extra |
Omitted |
The Message structure of the generated CLIENT_QUERY dnstap message contains the following fields:
| dnstap field | Value |
|---|---|
| Message type | CLIENT_QUERY |
| Socket family | INET or INET6 derived from the ETW source address |
| Socket protocol | UDP or TCP derived from the ETW TCP property |
| Query address | ETW Source property |
| Response address | ETW InterfaceIP property |
| Query port | ETW Port property |
| Query time (seconds) | ETW event timestamp seconds component |
| Query time (nanoseconds) | Nanosecond component derived from the ETW event timestamp |
| Query message | ETW PacketData field |
The Message structure of the generated CLIENT_RESPONSE dnstap message contains the following fields:
| dnstap field | Value |
|---|---|
| Message type | CLIENT_RESPONSE |
| Socket family | INET or INET6 derived from the ETW source address |
| Socket protocol | UDP or TCP derived from the ETW TCP property |
| Query address | ETW Destination property |
| Query port | ETW Port property |
| Response address | ETW InterfaceIP property |
| Response time (seconds) | ETW event timestamp seconds component |
| Response time (nanoseconds) | Nanosecond component derived from the ETW event timestamp |
| Response message | ETW PacketData field |
The Message structure of the generated RESOLVER_QUERY dnstap message contains the following fields:
| dnstap field | Value |
|---|---|
| Message type | RESOLVER_QUERY |
| Socket family | INET or INET6 derived from the ETW source address |
| Socket protocol | UDP or TCP derived from the ETW TCP property |
| Query address | ETW InterfaceIP property |
| Query port | ETW Port property |
| Query time (seconds) | ETW event timestamp seconds component |
| Query time (nanoseconds) | Nanosecond component derived from the ETW event timestamp |
| Query message | ETW PacketData field |
| Response address | ETW Destination property |
The Message structure of the generated RESOLVER_RESPONSE dnstap message contains the following fields:
| dnstap field | Value |
|---|---|
| Message type | RESOLVER_RESPONSE |
| Socket family | INET or INET6 derived from the ETW source address |
| Socket protocol | UDP or TCP derived from the ETW TCP property |
| Query address | ETW InterfaceIP property |
| Query port | ETW Port property |
| Response address | ETW Source property |
| Response time (seconds) | ETW event timestamp seconds component |
| Response time (nanoseconds) | Nanosecond component derived from the ETW event timestamp |
| Response message | ETW PacketData field |