{"slug":"network-flow-logs","title":"Network flow logs","tags":["tailscale","networking","logging"],"agent_summary":"Last validated: Jan 23, 2026","trigger_phrases":[],"runnable":false,"markdown":"\r\n# Network flow logs\r\n\r\nLast validated: Jan 23, 2026\r\n\r\nNetwork flow logs let you understand how and when nodes on your Tailscale network (known as a tailnet) connect to each other. You can export network logs for long-term storage, security analysis, threat detection, or incident investigation. You can also [stream logs](https://tailscale.com/docs/features/logging/log-streaming) to a security information and event management ( [SIEM](https://tailscale.com/learn/security-information-and-event-management)) system.\r\n\r\nThe data captured in network logs is the flow of network traffic, not the contents of network traffic. Tailscale does not and cannot inspect your traffic. For more information about how your data stays private, refer to our [Security page](https://tailscale.com/security).\r\n\r\nNetwork flow logs are available for the most recent 30 days.\r\n\r\nThis featureis available for [the Premium and Enterprise plans](https://tailscale.com/pricing).\r\n\r\nOnly nodes using Tailscale v1.34 or later can send networking telemetry to the Tailscale logs service.\r\n\r\n## [How it works](https://tailscale.com/docs/features/logging/network-flow-logs\\#how-it-works)\r\n\r\nWhen network flow logs are enabled (and not using [`--no-logs-no-support`](https://tailscale.com/docs/features/logging#opting-out-of-client-logging)), nodes report their flow information (for both ends of the connection) to the Tailscale logs service. A connection can be between:\r\n\r\n- Two nodes\r\n- A node and a device behind a subnet router\r\n- A node and a public device accessed through an exit node\r\n\r\nWhen the connection is between a node and a device behind a subnet router, the subnet router logs the connection. When the connection is between a node and a public device accessed through an exit node, the exit node logs the connection.\r\n\r\nLogs occur between transferred and received network connections, and entries exist for both ends.\r\n\r\nLogs occur at two layers: the virtual layer and the physical layer. The virtual layer is the Tailscale network (often with IP addresses in [`100.x.x.x`](https://tailscale.com/docs/concepts/tailscale-ip-addresses)) that Tailscale provides for each device. The physical layer involves all the physical network interfaces on a device. When one node transmits a packet to another, the packet must cross through the physical layer. The summation of all traffic routed at the virtual layer is generally equal to the traffic routed at the physical layer.\r\n\r\nTailscale centrally stores network logs and lets you export them. Tailscale does not log the actual contents or data of the network traffic.\r\n\r\n## [Network logs structure](https://tailscale.com/docs/features/logging/network-flow-logs\\#network-logs-structure)\r\n\r\nNetwork logs contain an array of messages that provide details about network flow activity. Each message contains the following components:\r\n\r\n- `nodeId`: The node that generated this log message. It is a globally unique identifier of a node. It is not the same value as the node name. If you want to map `nodeId` to a node name, you can use the [`/api/v2/device/:nodeId`](https://tailscale.com/api#tag/devices/GET/tailnet/%7Btailnet%7D/devices) method and examine the `name` field.\r\n- `logged`: The time in UTC that the Tailscale logs service recorded the message. Generally, the logged time is after the end time within a message.\r\n- `start`: The start time in UTC for the network traffic flow data in the message, as recorded by the node that generated the message.\r\n- `end`: The end time in UTC for the network traffic flow data in the message, as recorded by the node that generated the message.\r\n- `srcNode`: Information about the source node itself, which is the node that generated this log message. Explore the `Node` type in the following section for more information.\r\n- `dstNodes`: List of information about all destination nodes that the source node (for example, this node) communicated with. Explore the `Node` type for more information.\r\n- `virtualTraffic`: Counters for the network flow's virtual traffic. Virtual traffic is traffic that occurs between nodes in your tailnet.\r\n- `subnetTraffic`: Counters for the network flow's traffic routed through an advertised subnet router.\r\n- `exitTraffic`: Counters for the network flow's traffic routed through an exit node. For traffic from a node to a public device through an exit node, the source is the Tailscale IP address, but the protocol, source port, and destination are empty. For traffic responses from a public device to a node through an exit node, the destination is the Tailscale IP address, but the protocol, destination port, and source are empty. Tailscale doesn't gather granular information about individual connections to preserve privacy. If an administrator enables [Destination Logging](https://tailscale.com/docs/features/exit-nodes#destination-logging-in-network-flow-logs), the protocol, source port, and destination information are logged.\r\n- `physicalTraffic`: Counters for the network flow's traffic on the physical network layer that operates below the virtual Tailscale network. Traffic information at the physical layer is gathered at a slightly different time than the virtual layer, so packets flowing through the virtual layer may not exactly line up with those at the physical layer.\r\n\r\nStart and end times are specific to the node that generated the message. Timestamps may be subject to clock skew across different nodes.\r\n\r\nThe virtual, subnet, exit, and physical traffic counters consist of the following components:\r\n\r\n- `proto`: The [IANA Protocol Number](https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml) for the network flow: 6 for TCP, 17 for UDP. Empty for exit traffic, unless [Destination Logging](https://tailscale.com/docs/features/exit-nodes#destination-logging-in-network-flow-logs) is enabled.\r\n- `src`: The Tailscale IP address and port for the source of the network flow. The port number is not included for exit traffic, unless [Destination Logging](https://tailscale.com/docs/features/exit-nodes#destination-logging-in-network-flow-logs) is enabled.\r\n- `dst`: The IP address and port for the destination of the network flow. This IP address can be either a Tailscale IP address or an external IP address, such as on a private network or a public IP. Empty for exit traffic, unless [Destination Logging](https://tailscale.com/docs/features/exit-nodes#destination-logging-in-network-flow-logs) is enabled.\r\n- `txPackets`: Number of packets transmitted.\r\n- `txBytes`: Number of bytes transmitted.\r\n- `rxPackets`: Number of packets received.\r\n- `rxBytes`: Number of bytes received.\r\n\r\n## [Enable network flow logs](https://tailscale.com/docs/features/logging/network-flow-logs\\#enable-network-flow-logs)\r\n\r\nNetwork flow logs are disabled by default.\r\n\r\nYou must be an [Owner, Admin, Network admin, or IT admin](https://tailscale.com/docs/reference/user-roles) of a tailnet to enable Network flow logs.\r\n\r\n1. Open the [Network flow logs](https://login.tailscale.com/admin/logs/network) page of the admin console.\r\n2. Select **Start logging**.\r\n3. In the **Start logging network flows** dialog, select **Start logging**.\r\n\r\n## [Disable network flow logs](https://tailscale.com/docs/features/logging/network-flow-logs\\#disable-network-flow-logs)\r\n\r\nYou must be an [Owner, Admin, Network admin, or IT admin](https://tailscale.com/docs/reference/user-roles) of a tailnet to disable Network flow logs.\r\n\r\n1. Open the [Network flow logs](https://login.tailscale.com/admin/logs/network) page of the admin console.\r\n2. Select **Stop logging**.\r\n3. In the **Stop logging network flows** dialog, select **Stop logging**.\r\n\r\n## [Access network logs](https://tailscale.com/docs/features/logging/network-flow-logs\\#access-network-logs)\r\n\r\nYou must be an [Owner, Admin, Network admin, or IT admin](https://tailscale.com/docs/reference/user-roles) of a tailnet to access network logs.\r\n\r\nYou can access network logs using the Tailscale [API](https://tailscale.com/docs/reference/tailscale-api) or [log streaming](https://tailscale.com/docs/features/logging/network-flow-logs#network-flow-logs-streaming).\r\n\r\n### [Access network logs through the API](https://tailscale.com/docs/features/logging/network-flow-logs\\#access-network-logs-through-the-api)\r\n\r\nYou need an [API access token](https://tailscale.com/docs/reference/tailscale-api#authentication) with the `logs:network:read` scope to access network logs.\r\n\r\nThe response from the `https://api.tailscale.com/api/v2/tailnet/{$TAILNET_ID}/logging/network` endpoint call is in the form of the `Response` struct:\r\n\r\n```go\r\ntype Response struct {\r\n\tLogs []Message `json:\"logs\"`\r\n}\r\n```\r\n\r\nUsing Go syntax, the `Response` struct contains a slice of `Message` types. The `Message` struct is defined as:\r\n\r\n```go\r\ntype Message struct {\r\n\t// NodeID is the stable ID of the node that\r\n\t// generated this network log message.\r\n\tNodeID string `json:\"nodeId\"` // for example, \"n123456CNTRL\"\r\n\r\n\t// Logged is the timestamp of when the Tailscale logs service\r\n\t// recorded the network log message from a given node.\r\n\t// It is guaranteed to be within the start and end time ranges\r\n\t// specified in the API request.\r\n\t// All log messages are listed in chronological order\r\n\t// from oldest to newest.\r\n\tLogged time.Time `json:\"logged\"`\r\n\r\n\t// Start and End are the inclusive time ranges for the network\r\n\t// traffic flow information present in the message.\r\n\t// These timestamps are recorded by the node and subject\r\n\t// to clock skew across different nodes.\r\n\t// Generally speaking, the Logged timestamp is after End.\r\n\t//\r\n\t// Network logs are gathered in 5 second windows.\r\n\t// This may change in the future.\r\n\tStart time.Time `json:\"start\"`\r\n\tEnd time.Time `json:\"end\"`\r\n\r\n\t// SrcNode is information about the source node itself,\r\n\t// which is the node that generated this log message.\r\n\tSrcNode Node `json:\"srcNode,omitzero\"`\r\n\r\n\t// DstNodes is information about all destination nodes\r\n\t// that the source node (i.e., this node) communicated with.\r\n\tDstNodes []Node `json:\"dstNodes,omitzero\"`\r\n\r\n\t// VirtualTraffic records connection statistics for\r\n\t// node to node traffic.\r\n\t// Both the source and address are Tailscale IP addresses\r\n\t// (for example, 100.xx.xx.xx). The source is always the\r\n\t// Tailscale IP address of the current node.\r\n\tVirtualTraffic []ConnectionCounts `json:\"virtualTraffic\"`\r\n\r\n\t// SubnetTraffic records node to external traffic\r\n\t// on an explicitly advertised subnet route.\r\n\t//\r\n\t// For nodes using a subnet router,\r\n\t// the source is the Tailscale IP address of the current node and\r\n\t// the destination is the external IP address in the subnet range.\r\n\t// For nodes operating as the subnet router,\r\n\t// the destination is the Tailscale IP address of the node\r\n\t// using the subnet router and the source address\r\n\t// is the external IP address within the advertised subnet range.\r\n\tSubnetTraffic []ConnectionCounts `json:\"subnetTraffic\"`\r\n\r\n\t// ExitTraffic records aggregated statistics for all traffic\r\n\t// flowing through an exit node. For traffic from a node to a\r\n\t// public device through an exit node, the source will be the\r\n\t// Tailscale IP address, but the protocol, source port,\r\n\t// and destination will be empty. For traffic responses from a\r\n\t// public device to a node through an exit node, the destination\r\n\t// will be the Tailscale IP address, but the protocol,\r\n\t// destination port and source will be empty. Fine\r\n\t// granularity information about individual connections is not\r\n\t// gathered so that privacy can be preserved.\r\n\tExitTraffic []ConnectionCounts `json:\"exitTraffic\"`\r\n\r\n\t// PhysicalTraffic records traffic on the physical network layer\r\n\t// that operates below the virtual Tailscale network.\r\n\t// The source is the Tailscale IP address of remote nodes\r\n\t// that the current node is communicating with and\r\n\t// the destination is the external IP address that traffic\r\n\t// is physically sent to to communicate with that\r\n\t// remote node.\r\n\t//\r\n\t// Traffic information at the physical layer is gathered\r\n\t// at a slightly different moment in time as the virtual layer,\r\n\t// so packets flowing through the virtual layer\r\n\t// may not exactly line up with those at the physical layer.\r\n\tPhysicalTraffic []ConnectionCounts `json:\"physicalTraffic\"`\r\n}\r\n```\r\n\r\nSeveral fields in the `Message` struct use the type `ConnectionCounts`. The `ConnectionCounts` struct is defined as:\r\n\r\n```go\r\ntype ConnectionCounts struct {\r\n\tProto uint8  `json:\"proto\"` // for example, 6 for TCP, 17 for UDP\r\n\tSrc   string `json:\"src\"`   // for example, \"100.11.22.33:4567\"\r\n\tDst   string `json:\"dst\"`   // for example, \"192.55.66.77:80\"\r\n\r\n\tTxPackets uint64 `json:\"txPkts\"` // transferred packets\r\n\tTxBytes   uint64 `json:\"txBytes\"` // transferred bytes\r\n\tRxPackets uint64 `json:\"rxPkts\"` // received packets\r\n\tRxBytes   uint64 `json:\"rxBytes\"` // received bytes\r\n}\r\n```\r\n\r\nSeveral fields in the `Message` struct use the type `Node`. The `Node` struct is defined as:\r\n\r\n```go\r\ntype Node struct {\r\n  // NodeID is the stable ID of the node.\r\n  NodeID string `json:\"nodeId\"` // for example, \"n123456CNTRL\"\r\n\r\n  // Name is the fully-qualified hostname of the node.\r\n  Name string `json:\"name\"` // for example, \"carbonite.example.ts.net\"\r\n\r\n  // Addresses are the Tailscale IP addresses of the node.\r\n  Addresses []string `json:\"addresses\"` // for example, [\"100.12.34.56\", \"fd7a:115c:a1e0::0123:4567\"]\r\n\r\n  // OS is the operating system of the node.\r\n  OS string `json:\"os\"` // for example, \"linux\"\r\n\r\n  // User is the user that owns the node.\r\n  // It is not populated if the node is tagged.\r\n  User string `json:\"user\"` // for example, \"johndoe@example.com\"\r\n\r\n  // Tags are the tags of the node.\r\n  // It is not populated if the node is owned by a user.\r\n  Tags []string `json:\"tags\"` // for example, [\"tag:prod\",\"tag:logs\"]\r\n}\r\n```\r\n\r\nThe `Message.NodeID` field is verified by the Tailscale logs service as the actual node from which the message originated. The `Start`, `End`, `SrcNode`, `DstNodes`, `VirtualTraffic`, `SubnetTraffic`, `ExitTraffic`, and `PhysicalTraffic` fields are produced by individual nodes and recorded by the Tailscale logs service without validation. It is infeasible for Tailscale to verify the accuracy or truthfulness of this information. It is possible for malicious nodes to spoof this information.\r\n\r\nWhen investigating network flow logs, you should identify a set of nodes that you consider more trustworthy (such as a server running in production) in contrast to those that might be more likely tampered with (such as an individual employee's work laptop). Discrepancies in network logs between the two might be indicative of malicious behavior.\r\n\r\nYou can use the following query parameters with the API:\r\n\r\n- `start`: Required. Start of the timeframe, in [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) timestamp format, for the logs to retrieve. For example: `2022-07-20T00:00:00Z`.\r\n- `end`: Required. End of the timeframe, in RFC3339 timestamp format, for the logs to retrieve. If `end` is greater than the latest known timestamp in the log, the API call will not block the call. This means consecutive queries with the same `start` and `end` times range may return different log entries that were not available during the earlier query.\r\n\r\n`start` and `end` times are inclusive within nanosecond resolution.\r\n\r\nAll log messages are listed in chronological order from oldest to newest.\r\n\r\nThere is no pagination support or maximum page size for the API. All known logged network activity in the specified timeframe is returned.\r\n\r\n#### [Example API call](https://tailscale.com/docs/features/logging/network-flow-logs\\#example-api-call)\r\n\r\nThis example assumes you have set up the following variables to use for your API call:\r\n\r\n- `$ACCESS_TOKEN`: An [API access token](https://tailscale.com/docs/reference/tailscale-api#authentication) to use when calling the Tailscale API. You can create an API access token in the [Keys](https://login.tailscale.com/admin/settings/keys) page of the admin console.\r\n- `$TAILNET_ID`: Your tailnet ID. You can find your tailnet ID in the [General](https://login.tailscale.com/admin/settings/general) page of the admin console.\r\n- `$START`: The start of the timeframe for the logs to retrieve.\r\n- `$END`: The end of the timeframe for the logs to retrieve.\r\n\r\n```shell\r\nexport ACCESS_TOKEN=tskey-api-k123456CNTRL-0123456789abcdef\r\nexport TAILNET_ID=example.com\r\nexport START=2022-10-28T22:40:00.000000000Z\r\nexport END=2022-10-28T22:40:04.999999999Z\r\n```\r\n\r\nThis example makes a call to the `https://api.tailscale.com/api/v2/tailnet/{$TAILNET_ID}/logging/network` endpoint.\r\n\r\n```shell\r\ncurl -u $ACCESS_TOKEN: \\\r\n  \"https://api.tailscale.com/api/v2/tailnet/{$TAILNET_ID}/logging/network?start={$START}&end={$END}\"\r\n```\r\n\r\n(You can also copy the command above from the [Network flow logs](https://login.tailscale.com/admin/logs/network) page of the admin console.)\r\n\r\nThe following code block contains an example log output:\r\n\r\n```json\r\n{\r\n\t\"logs\": [\\\r\n\t\t {\\\r\n\t\t\t\"start\":  \"2025-10-28T22:39:51.890385065Z\",\\\r\n\t\t\t\"end\":    \"2025-10-28T22:39:56.886545512Z\",\\\r\n\t\t\t\"logged\": \"2025-10-28T22:40:00.290605382Z\",\\\r\n\\\r\n\t\t\t\"nodeId\": \"nBcdef1CNTRL\",\\\r\n\t\t\t\"srcNode\":\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"nodeId\": \"nBcdef1CNTRL\",\\\r\n\t\t\t\t\t\t\"addresses\": [\"100.111.22.33\", \"fd7a:115c:a1e0::c034:c374\"],\\\r\n\t\t\t\t\t\t\"os\": \"linux\",\\\r\n\t\t\t\t\t\t\"name\": \"pangolin.example.ts.net\",\\\r\n\t\t\t\t\t\t\"user\": \"joe@example.com\"\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\"dstNodes\": [\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"nodeId\": \"n22daC8CNTRL\",\\\r\n\t\t\t\t\t\t\"addresses\": [\"100.111.44.55\", \"fd7a:115c:a1e0::abcd:0123\"],\\\r\n\t\t\t\t\t\t\"os\": \"windows\",\\\r\n\t\t\t\t\t\t\"name\": \"alice-laptop.example.ts.net\",\\\r\n\t\t\t\t\t\t\"user\": \"alice@example.com\"\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"nodeId\": \"nX8fDaxCNTRL\",\\\r\n\t\t\t\t\t\t\"addresses\": [\"100.44.55.66\",  \"fd7a:115c:a1e0::a1b2:c3d4\"],\\\r\n\t\t\t\t\t\t\"os\": \"linux\",\\\r\n\t\t\t\t\t\t\"name\": \"prod.example.ts.net\",\\\r\n\t\t\t\t\t\t\"tags\": [\"tag:prod\"]},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"nodeId\": \"n7sUpZQCNTRL\",\\\r\n\t\t\t\t\t\t\"addresses\": [\"100.99.88.77\",  \"fd7a:115c:a1e0::91ab:84ab\"],\\\r\n\t\t\t\t\t\t\"os\": \"linux\",\\\r\n\t\t\t\t\t\t\"name\": \"logstream.remote.ts.net\",\\\r\n\t\t\t\t\t\t\"tags\": [\"tag:logstream\"]}\\\r\n\t\t\t],\\\r\n\t\t\t\"virtualTraffic\": [\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"proto\": 6,\\\r\n\t\t\t\t\t\t\"src\": \"100.111.22.33:21291\",\\\r\n\t\t\t\t\t\t\"dst\": \"100.111.44.55:63281\",\\\r\n\t\t\t\t\t\t\"txPkts\": 2,\\\r\n\t\t\t\t\t\t\"txBytes\": 108,\\\r\n\t\t\t\t\t\t\"rxPkts\": 2,\\\r\n\t\t\t\t\t\t\"rxBytes\": 112\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"proto\": 6,\\\r\n\t\t\t\t\t\t\"src\": \"100.111.22.33:864\",\\\r\n\t\t\t\t\t\t\"dst\": \"100.44.55.66:2049\",\\\r\n\t\t\t\t\t\t\"txPkts\": 6,\\\r\n\t\t\t\t\t\t\"txBytes\": 900,\\\r\n\t\t\t\t\t\t\"rxPkts\": 3,\\\r\n\t\t\t\t\t\t\"rxBytes\": 728\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"proto\": 6,\\\r\n\t\t\t\t\t\t\"src\": \"100.111.22.33:723\",\\\r\n\t\t\t\t\t\t\"dst\": \"100.99.88.77:2049\",\\\r\n\t\t\t\t\t\t\"txPkts\": 4,\\\r\n\t\t\t\t\t\t\"txBytes\": 596,\\\r\n\t\t\t\t\t\t\"rxPkts\": 2,\\\r\n\t\t\t\t\t\t\"rxBytes\": 432\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"proto\": 6,\\\r\n\t\t\t\t\t\t\"src\": \"100.111.22.33:21291\",\\\r\n\t\t\t\t\t\t\"dst\": \"100.111.44.55:63280\",\\\r\n\t\t\t\t\t\t\"txPkts\": 2,\\\r\n\t\t\t\t\t\t\"txBytes\": 108,\\\r\n\t\t\t\t\t\t\"rxPkts\": 2,\\\r\n\t\t\t\t\t\t\"rxBytes\": 112\\\r\n\t\t\t\t\t}\\\r\n\t\t\t],\\\r\n\t\t\t\"physicalTraffic\": [\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"src\": \"100.111.44.55:0\",\\\r\n\t\t\t\t\t\t\"dst\": \"192.55.66.77:41641\",\\\r\n\t\t\t\t\t\t\"txPkts\": 4,\\\r\n\t\t\t\t\t\t\"txBytes\": 384,\\\r\n\t\t\t\t\t\t\"rxPkts\": 4,\\\r\n\t\t\t\t\t\t\"rxBytes\": 384\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"src\": \"100.44.55.66:0\",\\\r\n\t\t\t\t\t\t\"dst\": \"192.168.0.101:41641\",\\\r\n\t\t\t\t\t\t\"txPkts\": 6,\\\r\n\t\t\t\t\t\t\"txBytes\": 1136,\\\r\n\t\t\t\t\t\t\"rxPkts\": 3,\\\r\n\t\t\t\t\t\t\"rxBytes\": 848\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"src\": \"100.99.88.77:0\",\\\r\n\t\t\t\t\t\t\"dst\": \"143.110.111.222:41641\",\\\r\n\t\t\t\t\t\t\"txPkts\": 4,\\\r\n\t\t\t\t\t\t\"txBytes\": 752,\\\r\n\t\t\t\t\t\t\"rxPkts\": 2,\\\r\n\t\t\t\t\t\t\"rxBytes\": 512\\\r\n\t\t\t\t\t}\\\r\n\t\t\t]\\\r\n\t\t}\\\r\n\t]\r\n}\r\n```\r\n\r\nYou can use the Go binary [`netlogfmt`](https://pkg.go.dev/tailscale.com/cmd/netlogfmt) to make the output more readable:\r\n\r\n```shell\r\ncurl -u $ACCESS_TOKEN: \\\r\n  \"https://api.tailscale.com/api/v2/tailnet/{$TAILNET_ID}/logging/network?start={$START}&end={$END}\" \\\r\n  | go run tailscale.com/cmd/netlogfmt@latest\r\n```\r\n\r\nThe following code block contains an example log output:\r\n\r\n```shell\r\n===========================================================================================\r\nNodeID: aBcdef1CNTRL\r\nLogged: 2022-10-28 15:40:00.290\r\nWindow: 2022-10-28 15:39:51.890 (4.996s)\r\n-----------------------------------------------------  Tx[P/s]   Tx[B/s]  Rx[P/s]   Rx[B/s]\r\nVirtualTraffic:                                          2.80    342.66     1.80    277.01\r\n    TCP:   100.111.22.33:864   -> 100.44.55.66:2049      1.20    180.14     0.60    145.71\r\n    TCP:   100.111.22.33:723   -> 100.99.88.77:2049      0.80    119.29     0.40     86.47\r\n    TCP:   100.111.22.33:21291 -> 100.111.44.55:63281    0.40     21.62     0.40     22.42\r\n    TCP:   100.111.22.33:21291 -> 100.111.44.55:63280    0.40     21.62     0.40     22.42\r\nPhysicalTraffic:                                         2.80    454.75     1.80    349.07\r\n                 100.44.55.66  -> 192.168.0.101:41641    1.20    227.37     0.60    169.73\r\n                 100.99.88.77  -> 143.111.222.333:41641  0.80    150.52     0.40    102.48\r\n                 100.111.44.55 -> 192.55.66.77:41641     0.80     76.86     0.80     76.86\r\n=============================================================================================\r\nNodeID: uvwXyz2CNTRL\r\nLogged: 2022-10-28 15:40:00.344\r\nWindow: 2022-10-28 15:39:53.286 (4.999s)\r\n-------------------------------------------------------  Tx[P/s]   Tx[B/s]  Rx[P/s]   Rx[B/s]\r\nVirtualTraffic:                                           28.60    3.32Ki    46.41    5.87Ki\r\n    TCP:    100.44.55.66:37500 -> 100.103.145.6:22         9.20    1.45Ki    13.60    2.46Ki\r\n    TCP:    100.44.55.66:49288 -> 100.99.88.77:22         12.80    1.22Ki    20.80    2.03Ki\r\n    TCP:     100.44.55.66:2049 -> 100.111.22.33:864        0.60   145.62     1.20    180.02\r\n    TCP:    100.44.55.66:49284 -> 100.99.88.77:22          1.00     88.01     2.00    236.03\r\n    TCP:    100.44.55.66:49282 -> 100.99.88.77:22          1.00     88.01     2.00    236.03\r\n    TCP:    100.44.55.66:49278 -> 100.99.88.77:22          1.00     88.01     2.00    236.03\r\n    TCP:    100.44.55.66:49280 -> 100.99.88.77:22          1.00     88.01     2.00    236.03\r\n    TCP:    100.44.55.66:49286 -> 100.99.88.77:22          1.00     88.01     1.80    193.62\r\n    ICMPv4:       100.44.55.66 -> 100.99.88.77             1.00     84.01     1.00     84.01\r\nPhysicalTraffic:                                          28.80    4.46Ki    46.41    7.74Ki\r\n                 100.99.88.77  -> 143.111.222.333:41641   18.80    2.48Ki    31.60    4.51Ki\r\n                 100.103.145.6 -> 64.71.162.170:41641      9.20    1.82Ki    13.60    3.01Ki\r\n                 100.111.22.33 -> 192.168.0.102:41641      0.60    169.62     1.20    227.23\r\n```\r\n\r\nTo make it easier to recognize nodes in the output, the `netlogfmt` binary provides flags that resolve IP addresses to readable labels:\r\n\r\n- `--resolve-addrs`: Convert Tailscale IP addresses to readable labels. Valid values include `nodeids` (which resolves IP addresses as node IDs), `names` (which resolves IP addresses as hostnames), or `users` (which resolves IP addresses as the user or tags that own the machine). Since Tailscale v1.92, network flow logs automatically embed node information directly into the logs. For logs generated by older clients, you must also specify `--api-key` and `--tailnet-name` as parameters to `netlogfmt` when using the `--resolve-addrs` flag.\r\n- `--api-key`: Specifies the [API access token](https://tailscale.com/docs/reference/tailscale-api#authentication) to use for the Tailscale API. This can be the same API access token you used for the `network-logs` endpoint or another valid API access token.\r\n- `--tailnet-name`: The same organization name you passed to the `network-logs` endpoint.\r\n\r\nThis example shows how to use the `netlogfmt` flags:\r\n\r\n```shell\r\ncurl -u $ACCESS_TOKEN:  -X GET \\\r\n  \"https://api.tailscale.com/api/v2/tailnet/{$TAILNET_ID}/logging/network?start={$START}&end={$END}\" \\\r\n  | go run tailscale.com/cmd/netlogfmt@latest --resolve-addrs=names --api-key=$ACCESS_TOKEN --tailnet-name=$TAILNET\r\n```\r\n\r\nAs mentioned above, the `ACCESS_TOKEN` and `TAILNET` is only needed to resolve addresses for clients older than v1.92.\r\n\r\nThe following code block contains an example log output.\r\n\r\n```shell\r\n=======================================================================================\r\nNodeID: aBcdef1CNTRL\r\nLogged: 2022-10-28 15:40:00.290\r\nWindow: 2022-10-28 15:39:51.890 (4.996s)\r\n-------------------------------------------------  Tx[P/s]   Tx[B/s]  Rx[P/s]   Rx[B/s]\r\nVirtualTraffic:                                      2.80    342.66     1.80    277.01\r\n    TCP:   carbonite:864 -> prism:2049               1.20    180.14     0.60    145.71\r\n    TCP:   carbonite:723 -> diamond:2049             0.80    119.29     0.40     86.47\r\n    TCP: carbonite:21291 -> glass:63281              0.40     21.62     0.40     22.42\r\n    TCP: carbonite:21291 -> glass:63280              0.40     21.62     0.40     22.42\r\nPhysicalTraffic:                                     2.80    454.75     1.80    349.07\r\n                   prism -> 192.168.0.101:41641      1.20    227.37     0.60    169.73\r\n                 diamond -> 143.110.111.222:41641    0.80    150.52     0.40    102.48\r\n                   glass -> 192.55.66.77:41641       0.80     76.86     0.80     76.86\r\n======================================================================================\r\nNodeID: uvwXyz2CNTRL\r\nLogged: 2022-10-28 15:40:00.344\r\nWindow: 2022-10-28 15:39:53.286 (4.999s)\r\n------------------------------------------------  Tx[P/s]   Tx[B/s]  Rx[P/s]   Rx[B/s]\r\nVirtualTraffic:                                    28.60    3.32Ki    46.41    5.87Ki\r\n    TCP:    prism:37500 -> glass:22                 9.20    1.45Ki    13.60    2.46Ki\r\n    TCP:    prism:49288 -> diamond:22              12.80    1.22Ki    20.80    2.03Ki\r\n    TCP:     prism:2049 -> carbonite:864            0.60    145.62     1.20    180.02\r\n    TCP:    prism:49284 -> diamond:22               1.00     88.01     2.00    236.03\r\n    TCP:    prism:49282 -> diamond:22               1.00     88.01     2.00    236.03\r\n    TCP:    prism:49278 -> diamond:22               1.00     88.01     2.00    236.03\r\n    TCP:    prism:49280 -> diamond:22               1.00     88.01     2.00    236.03\r\n    TCP:    prism:49286 -> diamond:22               1.00     88.01     1.80    193.62\r\n    ICMPv4:       prism -> diamond                  1.00     84.01     1.00     84.01\r\nPhysicalTraffic:                                   28.80    4.46Ki    46.41    7.74Ki\r\n                diamond -> 143.110.111.222:41641   18.80    2.48Ki    31.60    4.51Ki\r\n                  glass -> 64.71.111.222:41641      9.20    1.82Ki    13.60    3.01Ki\r\n              carbonite -> 192.168.0.102:41641      0.60    169.62     1.20    227.23\r\n```\r\n\r\n## [Network flow logs streaming](https://tailscale.com/docs/features/logging/network-flow-logs\\#network-flow-logs-streaming)\r\n\r\nLog streaming lets you stream network flow logs into a security information and event management ( [SIEM](https://tailscale.com/learn/security-information-and-event-management)) system. For more information, refer to [Log streaming](https://tailscale.com/docs/features/logging/log-streaming).\r\n\r\n## [Limitations](https://tailscale.com/docs/features/logging/network-flow-logs\\#limitations)\r\n\r\n- Only nodes using Tailscale v1.34 or later send networking telemetry to the Tailscale logs service.\r\n- You can only access network logs using the API and as a [streaming source](https://tailscale.com/docs/features/logging/log-streaming) for SIEM systems. There is no network logs viewing functionality in the Tailscale admin console.\r\n- Network flow logs are for logging, not monitoring. The admin console does not contain a live readout of the connections between nodes. Additionally, network logs don't include information on whether a node is online or idle. The logs only indicate whether there was network traffic.\r\n- Network logs do not include individual packet transfers. Logs capture when connections are active, which could include multiple data flows.\r\n- Tailscale only logs successful connects. If a connection attempt results in denied access, the attempt isn't logged.\r\n- Traffic information at the physical layer is gathered at a slightly different time than the virtual layer, so packets flowing through the virtual layer might not precisely line up with those at the physical layer.\r\n- Public IP addresses are not logged as either a destination or source. That is, a connection from your tailnet through an exit node does not log where the traffic is going, and a connection from the public internet through an exit node does not log where the traffic is returning from. To preserve privacy, Tailscale doesn't gather detailed information about individual connections.\r\n  - If [Destination Logging](https://tailscale.com/docs/features/exit-nodes#destination-logging-in-network-flow-logs) is enabled by the administrator, the protocol, source port, and destination information are logged.\r\n- The user authenticated on a source or destination host is not logged. To map a node to a user, you can use the [`/api/v2/tailnet/:tailnet/device`](https://tailscale.com/api#tag/devices/GET/tailnet/%7Btailnet%7D/devices) method and examine the `user` field.\r\n- Network logging is performed client-side. Tailscale cannot guarantee the delivery or integrity of the client logs. Tailscale cannot fully guarantee client log latency thresholds—that is, logs are not delivered in real-time.\r\n- Enabling network flow logs might result in a slight performance impact because the client does additional work to track necessary metrics. The incremental load is spread across the fleet, not concentrated on a single host.\r\n\r\n![Project Logo](https://cdn.brandfetch.io/tailscale.com/fallback/lettermark/theme/dark/h/256/w/256/icon?c=1bfwsmEH20zzEfSNTed)\r\n\r\nAsk AI\r\n\r\nreCAPTCHA\r\n\r\nRecaptcha requires verification.\r\n\r\nprotected by **reCAPTCHA**\r\n","html":"<h1>Network flow logs</h1>\n<p>Last validated: Jan 23, 2026</p>\n<p>Network flow logs let you understand how and when nodes on your Tailscale network (known as a tailnet) connect to each other. You can export network logs for long-term storage, security analysis, threat detection, or incident investigation. You can also <a href=\"https://tailscale.com/docs/features/logging/log-streaming\">stream logs</a> to a security information and event management ( <a href=\"https://tailscale.com/learn/security-information-and-event-management\">SIEM</a>) system.</p>\n<p>The data captured in network logs is the flow of network traffic, not the contents of network traffic. Tailscale does not and cannot inspect your traffic. For more information about how your data stays private, refer to our <a href=\"https://tailscale.com/security\">Security page</a>.</p>\n<p>Network flow logs are available for the most recent 30 days.</p>\n<p>This featureis available for <a href=\"https://tailscale.com/pricing\">the Premium and Enterprise plans</a>.</p>\n<p>Only nodes using Tailscale v1.34 or later can send networking telemetry to the Tailscale logs service.</p>\n<h2><a href=\"https://tailscale.com/docs/features/logging/network-flow-logs#how-it-works\">How it works</a></h2>\n<p>When network flow logs are enabled (and not using <a href=\"https://tailscale.com/docs/features/logging#opting-out-of-client-logging\"><code>--no-logs-no-support</code></a>), nodes report their flow information (for both ends of the connection) to the Tailscale logs service. A connection can be between:</p>\n<ul>\n<li>Two nodes</li>\n<li>A node and a device behind a subnet router</li>\n<li>A node and a public device accessed through an exit node</li>\n</ul>\n<p>When the connection is between a node and a device behind a subnet router, the subnet router logs the connection. When the connection is between a node and a public device accessed through an exit node, the exit node logs the connection.</p>\n<p>Logs occur between transferred and received network connections, and entries exist for both ends.</p>\n<p>Logs occur at two layers: the virtual layer and the physical layer. The virtual layer is the Tailscale network (often with IP addresses in <a href=\"https://tailscale.com/docs/concepts/tailscale-ip-addresses\"><code>100.x.x.x</code></a>) that Tailscale provides for each device. The physical layer involves all the physical network interfaces on a device. When one node transmits a packet to another, the packet must cross through the physical layer. The summation of all traffic routed at the virtual layer is generally equal to the traffic routed at the physical layer.</p>\n<p>Tailscale centrally stores network logs and lets you export them. Tailscale does not log the actual contents or data of the network traffic.</p>\n<h2><a href=\"https://tailscale.com/docs/features/logging/network-flow-logs#network-logs-structure\">Network logs structure</a></h2>\n<p>Network logs contain an array of messages that provide details about network flow activity. Each message contains the following components:</p>\n<ul>\n<li><code>nodeId</code>: The node that generated this log message. It is a globally unique identifier of a node. It is not the same value as the node name. If you want to map <code>nodeId</code> to a node name, you can use the <a href=\"https://tailscale.com/api#tag/devices/GET/tailnet/%7Btailnet%7D/devices\"><code>/api/v2/device/:nodeId</code></a> method and examine the <code>name</code> field.</li>\n<li><code>logged</code>: The time in UTC that the Tailscale logs service recorded the message. Generally, the logged time is after the end time within a message.</li>\n<li><code>start</code>: The start time in UTC for the network traffic flow data in the message, as recorded by the node that generated the message.</li>\n<li><code>end</code>: The end time in UTC for the network traffic flow data in the message, as recorded by the node that generated the message.</li>\n<li><code>srcNode</code>: Information about the source node itself, which is the node that generated this log message. Explore the <code>Node</code> type in the following section for more information.</li>\n<li><code>dstNodes</code>: List of information about all destination nodes that the source node (for example, this node) communicated with. Explore the <code>Node</code> type for more information.</li>\n<li><code>virtualTraffic</code>: Counters for the network flow's virtual traffic. Virtual traffic is traffic that occurs between nodes in your tailnet.</li>\n<li><code>subnetTraffic</code>: Counters for the network flow's traffic routed through an advertised subnet router.</li>\n<li><code>exitTraffic</code>: Counters for the network flow's traffic routed through an exit node. For traffic from a node to a public device through an exit node, the source is the Tailscale IP address, but the protocol, source port, and destination are empty. For traffic responses from a public device to a node through an exit node, the destination is the Tailscale IP address, but the protocol, destination port, and source are empty. Tailscale doesn't gather granular information about individual connections to preserve privacy. If an administrator enables <a href=\"https://tailscale.com/docs/features/exit-nodes#destination-logging-in-network-flow-logs\">Destination Logging</a>, the protocol, source port, and destination information are logged.</li>\n<li><code>physicalTraffic</code>: Counters for the network flow's traffic on the physical network layer that operates below the virtual Tailscale network. Traffic information at the physical layer is gathered at a slightly different time than the virtual layer, so packets flowing through the virtual layer may not exactly line up with those at the physical layer.</li>\n</ul>\n<p>Start and end times are specific to the node that generated the message. Timestamps may be subject to clock skew across different nodes.</p>\n<p>The virtual, subnet, exit, and physical traffic counters consist of the following components:</p>\n<ul>\n<li><code>proto</code>: The <a href=\"https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml\">IANA Protocol Number</a> for the network flow: 6 for TCP, 17 for UDP. Empty for exit traffic, unless <a href=\"https://tailscale.com/docs/features/exit-nodes#destination-logging-in-network-flow-logs\">Destination Logging</a> is enabled.</li>\n<li><code>src</code>: The Tailscale IP address and port for the source of the network flow. The port number is not included for exit traffic, unless <a href=\"https://tailscale.com/docs/features/exit-nodes#destination-logging-in-network-flow-logs\">Destination Logging</a> is enabled.</li>\n<li><code>dst</code>: The IP address and port for the destination of the network flow. This IP address can be either a Tailscale IP address or an external IP address, such as on a private network or a public IP. Empty for exit traffic, unless <a href=\"https://tailscale.com/docs/features/exit-nodes#destination-logging-in-network-flow-logs\">Destination Logging</a> is enabled.</li>\n<li><code>txPackets</code>: Number of packets transmitted.</li>\n<li><code>txBytes</code>: Number of bytes transmitted.</li>\n<li><code>rxPackets</code>: Number of packets received.</li>\n<li><code>rxBytes</code>: Number of bytes received.</li>\n</ul>\n<h2><a href=\"https://tailscale.com/docs/features/logging/network-flow-logs#enable-network-flow-logs\">Enable network flow logs</a></h2>\n<p>Network flow logs are disabled by default.</p>\n<p>You must be an <a href=\"https://tailscale.com/docs/reference/user-roles\">Owner, Admin, Network admin, or IT admin</a> of a tailnet to enable Network flow logs.</p>\n<ol>\n<li>Open the <a href=\"https://login.tailscale.com/admin/logs/network\">Network flow logs</a> page of the admin console.</li>\n<li>Select <strong>Start logging</strong>.</li>\n<li>In the <strong>Start logging network flows</strong> dialog, select <strong>Start logging</strong>.</li>\n</ol>\n<h2><a href=\"https://tailscale.com/docs/features/logging/network-flow-logs#disable-network-flow-logs\">Disable network flow logs</a></h2>\n<p>You must be an <a href=\"https://tailscale.com/docs/reference/user-roles\">Owner, Admin, Network admin, or IT admin</a> of a tailnet to disable Network flow logs.</p>\n<ol>\n<li>Open the <a href=\"https://login.tailscale.com/admin/logs/network\">Network flow logs</a> page of the admin console.</li>\n<li>Select <strong>Stop logging</strong>.</li>\n<li>In the <strong>Stop logging network flows</strong> dialog, select <strong>Stop logging</strong>.</li>\n</ol>\n<h2><a href=\"https://tailscale.com/docs/features/logging/network-flow-logs#access-network-logs\">Access network logs</a></h2>\n<p>You must be an <a href=\"https://tailscale.com/docs/reference/user-roles\">Owner, Admin, Network admin, or IT admin</a> of a tailnet to access network logs.</p>\n<p>You can access network logs using the Tailscale <a href=\"https://tailscale.com/docs/reference/tailscale-api\">API</a> or <a href=\"https://tailscale.com/docs/features/logging/network-flow-logs#network-flow-logs-streaming\">log streaming</a>.</p>\n<h3><a href=\"https://tailscale.com/docs/features/logging/network-flow-logs#access-network-logs-through-the-api\">Access network logs through the API</a></h3>\n<p>You need an <a href=\"https://tailscale.com/docs/reference/tailscale-api#authentication\">API access token</a> with the <code>logs:network:read</code> scope to access network logs.</p>\n<p>The response from the <code>https://api.tailscale.com/api/v2/tailnet/{$TAILNET_ID}/logging/network</code> endpoint call is in the form of the <code>Response</code> struct:</p>\n<pre><code class=\"language-go\">type Response struct {\r\n\tLogs []Message `json:\"logs\"`\r\n}\n</code></pre>\n<p>Using Go syntax, the <code>Response</code> struct contains a slice of <code>Message</code> types. The <code>Message</code> struct is defined as:</p>\n<pre><code class=\"language-go\">type Message struct {\r\n\t// NodeID is the stable ID of the node that\r\n\t// generated this network log message.\r\n\tNodeID string `json:\"nodeId\"` // for example, \"n123456CNTRL\"\r\n\r\n\t// Logged is the timestamp of when the Tailscale logs service\r\n\t// recorded the network log message from a given node.\r\n\t// It is guaranteed to be within the start and end time ranges\r\n\t// specified in the API request.\r\n\t// All log messages are listed in chronological order\r\n\t// from oldest to newest.\r\n\tLogged time.Time `json:\"logged\"`\r\n\r\n\t// Start and End are the inclusive time ranges for the network\r\n\t// traffic flow information present in the message.\r\n\t// These timestamps are recorded by the node and subject\r\n\t// to clock skew across different nodes.\r\n\t// Generally speaking, the Logged timestamp is after End.\r\n\t//\r\n\t// Network logs are gathered in 5 second windows.\r\n\t// This may change in the future.\r\n\tStart time.Time `json:\"start\"`\r\n\tEnd time.Time `json:\"end\"`\r\n\r\n\t// SrcNode is information about the source node itself,\r\n\t// which is the node that generated this log message.\r\n\tSrcNode Node `json:\"srcNode,omitzero\"`\r\n\r\n\t// DstNodes is information about all destination nodes\r\n\t// that the source node (i.e., this node) communicated with.\r\n\tDstNodes []Node `json:\"dstNodes,omitzero\"`\r\n\r\n\t// VirtualTraffic records connection statistics for\r\n\t// node to node traffic.\r\n\t// Both the source and address are Tailscale IP addresses\r\n\t// (for example, 100.xx.xx.xx). The source is always the\r\n\t// Tailscale IP address of the current node.\r\n\tVirtualTraffic []ConnectionCounts `json:\"virtualTraffic\"`\r\n\r\n\t// SubnetTraffic records node to external traffic\r\n\t// on an explicitly advertised subnet route.\r\n\t//\r\n\t// For nodes using a subnet router,\r\n\t// the source is the Tailscale IP address of the current node and\r\n\t// the destination is the external IP address in the subnet range.\r\n\t// For nodes operating as the subnet router,\r\n\t// the destination is the Tailscale IP address of the node\r\n\t// using the subnet router and the source address\r\n\t// is the external IP address within the advertised subnet range.\r\n\tSubnetTraffic []ConnectionCounts `json:\"subnetTraffic\"`\r\n\r\n\t// ExitTraffic records aggregated statistics for all traffic\r\n\t// flowing through an exit node. For traffic from a node to a\r\n\t// public device through an exit node, the source will be the\r\n\t// Tailscale IP address, but the protocol, source port,\r\n\t// and destination will be empty. For traffic responses from a\r\n\t// public device to a node through an exit node, the destination\r\n\t// will be the Tailscale IP address, but the protocol,\r\n\t// destination port and source will be empty. Fine\r\n\t// granularity information about individual connections is not\r\n\t// gathered so that privacy can be preserved.\r\n\tExitTraffic []ConnectionCounts `json:\"exitTraffic\"`\r\n\r\n\t// PhysicalTraffic records traffic on the physical network layer\r\n\t// that operates below the virtual Tailscale network.\r\n\t// The source is the Tailscale IP address of remote nodes\r\n\t// that the current node is communicating with and\r\n\t// the destination is the external IP address that traffic\r\n\t// is physically sent to to communicate with that\r\n\t// remote node.\r\n\t//\r\n\t// Traffic information at the physical layer is gathered\r\n\t// at a slightly different moment in time as the virtual layer,\r\n\t// so packets flowing through the virtual layer\r\n\t// may not exactly line up with those at the physical layer.\r\n\tPhysicalTraffic []ConnectionCounts `json:\"physicalTraffic\"`\r\n}\n</code></pre>\n<p>Several fields in the <code>Message</code> struct use the type <code>ConnectionCounts</code>. The <code>ConnectionCounts</code> struct is defined as:</p>\n<pre><code class=\"language-go\">type ConnectionCounts struct {\r\n\tProto uint8  `json:\"proto\"` // for example, 6 for TCP, 17 for UDP\r\n\tSrc   string `json:\"src\"`   // for example, \"100.11.22.33:4567\"\r\n\tDst   string `json:\"dst\"`   // for example, \"192.55.66.77:80\"\r\n\r\n\tTxPackets uint64 `json:\"txPkts\"` // transferred packets\r\n\tTxBytes   uint64 `json:\"txBytes\"` // transferred bytes\r\n\tRxPackets uint64 `json:\"rxPkts\"` // received packets\r\n\tRxBytes   uint64 `json:\"rxBytes\"` // received bytes\r\n}\n</code></pre>\n<p>Several fields in the <code>Message</code> struct use the type <code>Node</code>. The <code>Node</code> struct is defined as:</p>\n<pre><code class=\"language-go\">type Node struct {\r\n  // NodeID is the stable ID of the node.\r\n  NodeID string `json:\"nodeId\"` // for example, \"n123456CNTRL\"\r\n\r\n  // Name is the fully-qualified hostname of the node.\r\n  Name string `json:\"name\"` // for example, \"carbonite.example.ts.net\"\r\n\r\n  // Addresses are the Tailscale IP addresses of the node.\r\n  Addresses []string `json:\"addresses\"` // for example, [\"100.12.34.56\", \"fd7a:115c:a1e0::0123:4567\"]\r\n\r\n  // OS is the operating system of the node.\r\n  OS string `json:\"os\"` // for example, \"linux\"\r\n\r\n  // User is the user that owns the node.\r\n  // It is not populated if the node is tagged.\r\n  User string `json:\"user\"` // for example, \"johndoe@example.com\"\r\n\r\n  // Tags are the tags of the node.\r\n  // It is not populated if the node is owned by a user.\r\n  Tags []string `json:\"tags\"` // for example, [\"tag:prod\",\"tag:logs\"]\r\n}\n</code></pre>\n<p>The <code>Message.NodeID</code> field is verified by the Tailscale logs service as the actual node from which the message originated. The <code>Start</code>, <code>End</code>, <code>SrcNode</code>, <code>DstNodes</code>, <code>VirtualTraffic</code>, <code>SubnetTraffic</code>, <code>ExitTraffic</code>, and <code>PhysicalTraffic</code> fields are produced by individual nodes and recorded by the Tailscale logs service without validation. It is infeasible for Tailscale to verify the accuracy or truthfulness of this information. It is possible for malicious nodes to spoof this information.</p>\n<p>When investigating network flow logs, you should identify a set of nodes that you consider more trustworthy (such as a server running in production) in contrast to those that might be more likely tampered with (such as an individual employee's work laptop). Discrepancies in network logs between the two might be indicative of malicious behavior.</p>\n<p>You can use the following query parameters with the API:</p>\n<ul>\n<li><code>start</code>: Required. Start of the timeframe, in <a href=\"https://www.rfc-editor.org/rfc/rfc3339.html\">RFC 3339</a> timestamp format, for the logs to retrieve. For example: <code>2022-07-20T00:00:00Z</code>.</li>\n<li><code>end</code>: Required. End of the timeframe, in RFC3339 timestamp format, for the logs to retrieve. If <code>end</code> is greater than the latest known timestamp in the log, the API call will not block the call. This means consecutive queries with the same <code>start</code> and <code>end</code> times range may return different log entries that were not available during the earlier query.</li>\n</ul>\n<p><code>start</code> and <code>end</code> times are inclusive within nanosecond resolution.</p>\n<p>All log messages are listed in chronological order from oldest to newest.</p>\n<p>There is no pagination support or maximum page size for the API. All known logged network activity in the specified timeframe is returned.</p>\n<h4><a href=\"https://tailscale.com/docs/features/logging/network-flow-logs#example-api-call\">Example API call</a></h4>\n<p>This example assumes you have set up the following variables to use for your API call:</p>\n<ul>\n<li><code>$ACCESS_TOKEN</code>: An <a href=\"https://tailscale.com/docs/reference/tailscale-api#authentication\">API access token</a> to use when calling the Tailscale API. You can create an API access token in the <a href=\"https://login.tailscale.com/admin/settings/keys\">Keys</a> page of the admin console.</li>\n<li><code>$TAILNET_ID</code>: Your tailnet ID. You can find your tailnet ID in the <a href=\"https://login.tailscale.com/admin/settings/general\">General</a> page of the admin console.</li>\n<li><code>$START</code>: The start of the timeframe for the logs to retrieve.</li>\n<li><code>$END</code>: The end of the timeframe for the logs to retrieve.</li>\n</ul>\n<pre><code class=\"language-shell\">export ACCESS_TOKEN=tskey-api-k123456CNTRL-0123456789abcdef\r\nexport TAILNET_ID=example.com\r\nexport START=2022-10-28T22:40:00.000000000Z\r\nexport END=2022-10-28T22:40:04.999999999Z\n</code></pre>\n<p>This example makes a call to the <code>https://api.tailscale.com/api/v2/tailnet/{$TAILNET_ID}/logging/network</code> endpoint.</p>\n<pre><code class=\"language-shell\">curl -u $ACCESS_TOKEN: \\\r\n  \"https://api.tailscale.com/api/v2/tailnet/{$TAILNET_ID}/logging/network?start={$START}&#x26;end={$END}\"\n</code></pre>\n<p>(You can also copy the command above from the <a href=\"https://login.tailscale.com/admin/logs/network\">Network flow logs</a> page of the admin console.)</p>\n<p>The following code block contains an example log output:</p>\n<pre><code class=\"language-json\">{\r\n\t\"logs\": [\\\r\n\t\t {\\\r\n\t\t\t\"start\":  \"2025-10-28T22:39:51.890385065Z\",\\\r\n\t\t\t\"end\":    \"2025-10-28T22:39:56.886545512Z\",\\\r\n\t\t\t\"logged\": \"2025-10-28T22:40:00.290605382Z\",\\\r\n\\\r\n\t\t\t\"nodeId\": \"nBcdef1CNTRL\",\\\r\n\t\t\t\"srcNode\":\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"nodeId\": \"nBcdef1CNTRL\",\\\r\n\t\t\t\t\t\t\"addresses\": [\"100.111.22.33\", \"fd7a:115c:a1e0::c034:c374\"],\\\r\n\t\t\t\t\t\t\"os\": \"linux\",\\\r\n\t\t\t\t\t\t\"name\": \"pangolin.example.ts.net\",\\\r\n\t\t\t\t\t\t\"user\": \"joe@example.com\"\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\"dstNodes\": [\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"nodeId\": \"n22daC8CNTRL\",\\\r\n\t\t\t\t\t\t\"addresses\": [\"100.111.44.55\", \"fd7a:115c:a1e0::abcd:0123\"],\\\r\n\t\t\t\t\t\t\"os\": \"windows\",\\\r\n\t\t\t\t\t\t\"name\": \"alice-laptop.example.ts.net\",\\\r\n\t\t\t\t\t\t\"user\": \"alice@example.com\"\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"nodeId\": \"nX8fDaxCNTRL\",\\\r\n\t\t\t\t\t\t\"addresses\": [\"100.44.55.66\",  \"fd7a:115c:a1e0::a1b2:c3d4\"],\\\r\n\t\t\t\t\t\t\"os\": \"linux\",\\\r\n\t\t\t\t\t\t\"name\": \"prod.example.ts.net\",\\\r\n\t\t\t\t\t\t\"tags\": [\"tag:prod\"]},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"nodeId\": \"n7sUpZQCNTRL\",\\\r\n\t\t\t\t\t\t\"addresses\": [\"100.99.88.77\",  \"fd7a:115c:a1e0::91ab:84ab\"],\\\r\n\t\t\t\t\t\t\"os\": \"linux\",\\\r\n\t\t\t\t\t\t\"name\": \"logstream.remote.ts.net\",\\\r\n\t\t\t\t\t\t\"tags\": [\"tag:logstream\"]}\\\r\n\t\t\t],\\\r\n\t\t\t\"virtualTraffic\": [\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"proto\": 6,\\\r\n\t\t\t\t\t\t\"src\": \"100.111.22.33:21291\",\\\r\n\t\t\t\t\t\t\"dst\": \"100.111.44.55:63281\",\\\r\n\t\t\t\t\t\t\"txPkts\": 2,\\\r\n\t\t\t\t\t\t\"txBytes\": 108,\\\r\n\t\t\t\t\t\t\"rxPkts\": 2,\\\r\n\t\t\t\t\t\t\"rxBytes\": 112\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"proto\": 6,\\\r\n\t\t\t\t\t\t\"src\": \"100.111.22.33:864\",\\\r\n\t\t\t\t\t\t\"dst\": \"100.44.55.66:2049\",\\\r\n\t\t\t\t\t\t\"txPkts\": 6,\\\r\n\t\t\t\t\t\t\"txBytes\": 900,\\\r\n\t\t\t\t\t\t\"rxPkts\": 3,\\\r\n\t\t\t\t\t\t\"rxBytes\": 728\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"proto\": 6,\\\r\n\t\t\t\t\t\t\"src\": \"100.111.22.33:723\",\\\r\n\t\t\t\t\t\t\"dst\": \"100.99.88.77:2049\",\\\r\n\t\t\t\t\t\t\"txPkts\": 4,\\\r\n\t\t\t\t\t\t\"txBytes\": 596,\\\r\n\t\t\t\t\t\t\"rxPkts\": 2,\\\r\n\t\t\t\t\t\t\"rxBytes\": 432\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"proto\": 6,\\\r\n\t\t\t\t\t\t\"src\": \"100.111.22.33:21291\",\\\r\n\t\t\t\t\t\t\"dst\": \"100.111.44.55:63280\",\\\r\n\t\t\t\t\t\t\"txPkts\": 2,\\\r\n\t\t\t\t\t\t\"txBytes\": 108,\\\r\n\t\t\t\t\t\t\"rxPkts\": 2,\\\r\n\t\t\t\t\t\t\"rxBytes\": 112\\\r\n\t\t\t\t\t}\\\r\n\t\t\t],\\\r\n\t\t\t\"physicalTraffic\": [\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"src\": \"100.111.44.55:0\",\\\r\n\t\t\t\t\t\t\"dst\": \"192.55.66.77:41641\",\\\r\n\t\t\t\t\t\t\"txPkts\": 4,\\\r\n\t\t\t\t\t\t\"txBytes\": 384,\\\r\n\t\t\t\t\t\t\"rxPkts\": 4,\\\r\n\t\t\t\t\t\t\"rxBytes\": 384\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"src\": \"100.44.55.66:0\",\\\r\n\t\t\t\t\t\t\"dst\": \"192.168.0.101:41641\",\\\r\n\t\t\t\t\t\t\"txPkts\": 6,\\\r\n\t\t\t\t\t\t\"txBytes\": 1136,\\\r\n\t\t\t\t\t\t\"rxPkts\": 3,\\\r\n\t\t\t\t\t\t\"rxBytes\": 848\\\r\n\t\t\t\t\t},\\\r\n\t\t\t\t\t{\\\r\n\t\t\t\t\t\t\"src\": \"100.99.88.77:0\",\\\r\n\t\t\t\t\t\t\"dst\": \"143.110.111.222:41641\",\\\r\n\t\t\t\t\t\t\"txPkts\": 4,\\\r\n\t\t\t\t\t\t\"txBytes\": 752,\\\r\n\t\t\t\t\t\t\"rxPkts\": 2,\\\r\n\t\t\t\t\t\t\"rxBytes\": 512\\\r\n\t\t\t\t\t}\\\r\n\t\t\t]\\\r\n\t\t}\\\r\n\t]\r\n}\n</code></pre>\n<p>You can use the Go binary <a href=\"https://pkg.go.dev/tailscale.com/cmd/netlogfmt\"><code>netlogfmt</code></a> to make the output more readable:</p>\n<pre><code class=\"language-shell\">curl -u $ACCESS_TOKEN: \\\r\n  \"https://api.tailscale.com/api/v2/tailnet/{$TAILNET_ID}/logging/network?start={$START}&#x26;end={$END}\" \\\r\n  | go run tailscale.com/cmd/netlogfmt@latest\n</code></pre>\n<p>The following code block contains an example log output:</p>\n<pre><code class=\"language-shell\">===========================================================================================\r\nNodeID: aBcdef1CNTRL\r\nLogged: 2022-10-28 15:40:00.290\r\nWindow: 2022-10-28 15:39:51.890 (4.996s)\r\n-----------------------------------------------------  Tx[P/s]   Tx[B/s]  Rx[P/s]   Rx[B/s]\r\nVirtualTraffic:                                          2.80    342.66     1.80    277.01\r\n    TCP:   100.111.22.33:864   -> 100.44.55.66:2049      1.20    180.14     0.60    145.71\r\n    TCP:   100.111.22.33:723   -> 100.99.88.77:2049      0.80    119.29     0.40     86.47\r\n    TCP:   100.111.22.33:21291 -> 100.111.44.55:63281    0.40     21.62     0.40     22.42\r\n    TCP:   100.111.22.33:21291 -> 100.111.44.55:63280    0.40     21.62     0.40     22.42\r\nPhysicalTraffic:                                         2.80    454.75     1.80    349.07\r\n                 100.44.55.66  -> 192.168.0.101:41641    1.20    227.37     0.60    169.73\r\n                 100.99.88.77  -> 143.111.222.333:41641  0.80    150.52     0.40    102.48\r\n                 100.111.44.55 -> 192.55.66.77:41641     0.80     76.86     0.80     76.86\r\n=============================================================================================\r\nNodeID: uvwXyz2CNTRL\r\nLogged: 2022-10-28 15:40:00.344\r\nWindow: 2022-10-28 15:39:53.286 (4.999s)\r\n-------------------------------------------------------  Tx[P/s]   Tx[B/s]  Rx[P/s]   Rx[B/s]\r\nVirtualTraffic:                                           28.60    3.32Ki    46.41    5.87Ki\r\n    TCP:    100.44.55.66:37500 -> 100.103.145.6:22         9.20    1.45Ki    13.60    2.46Ki\r\n    TCP:    100.44.55.66:49288 -> 100.99.88.77:22         12.80    1.22Ki    20.80    2.03Ki\r\n    TCP:     100.44.55.66:2049 -> 100.111.22.33:864        0.60   145.62     1.20    180.02\r\n    TCP:    100.44.55.66:49284 -> 100.99.88.77:22          1.00     88.01     2.00    236.03\r\n    TCP:    100.44.55.66:49282 -> 100.99.88.77:22          1.00     88.01     2.00    236.03\r\n    TCP:    100.44.55.66:49278 -> 100.99.88.77:22          1.00     88.01     2.00    236.03\r\n    TCP:    100.44.55.66:49280 -> 100.99.88.77:22          1.00     88.01     2.00    236.03\r\n    TCP:    100.44.55.66:49286 -> 100.99.88.77:22          1.00     88.01     1.80    193.62\r\n    ICMPv4:       100.44.55.66 -> 100.99.88.77             1.00     84.01     1.00     84.01\r\nPhysicalTraffic:                                          28.80    4.46Ki    46.41    7.74Ki\r\n                 100.99.88.77  -> 143.111.222.333:41641   18.80    2.48Ki    31.60    4.51Ki\r\n                 100.103.145.6 -> 64.71.162.170:41641      9.20    1.82Ki    13.60    3.01Ki\r\n                 100.111.22.33 -> 192.168.0.102:41641      0.60    169.62     1.20    227.23\n</code></pre>\n<p>To make it easier to recognize nodes in the output, the <code>netlogfmt</code> binary provides flags that resolve IP addresses to readable labels:</p>\n<ul>\n<li><code>--resolve-addrs</code>: Convert Tailscale IP addresses to readable labels. Valid values include <code>nodeids</code> (which resolves IP addresses as node IDs), <code>names</code> (which resolves IP addresses as hostnames), or <code>users</code> (which resolves IP addresses as the user or tags that own the machine). Since Tailscale v1.92, network flow logs automatically embed node information directly into the logs. For logs generated by older clients, you must also specify <code>--api-key</code> and <code>--tailnet-name</code> as parameters to <code>netlogfmt</code> when using the <code>--resolve-addrs</code> flag.</li>\n<li><code>--api-key</code>: Specifies the <a href=\"https://tailscale.com/docs/reference/tailscale-api#authentication\">API access token</a> to use for the Tailscale API. This can be the same API access token you used for the <code>network-logs</code> endpoint or another valid API access token.</li>\n<li><code>--tailnet-name</code>: The same organization name you passed to the <code>network-logs</code> endpoint.</li>\n</ul>\n<p>This example shows how to use the <code>netlogfmt</code> flags:</p>\n<pre><code class=\"language-shell\">curl -u $ACCESS_TOKEN:  -X GET \\\r\n  \"https://api.tailscale.com/api/v2/tailnet/{$TAILNET_ID}/logging/network?start={$START}&#x26;end={$END}\" \\\r\n  | go run tailscale.com/cmd/netlogfmt@latest --resolve-addrs=names --api-key=$ACCESS_TOKEN --tailnet-name=$TAILNET\n</code></pre>\n<p>As mentioned above, the <code>ACCESS_TOKEN</code> and <code>TAILNET</code> is only needed to resolve addresses for clients older than v1.92.</p>\n<p>The following code block contains an example log output.</p>\n<pre><code class=\"language-shell\">=======================================================================================\r\nNodeID: aBcdef1CNTRL\r\nLogged: 2022-10-28 15:40:00.290\r\nWindow: 2022-10-28 15:39:51.890 (4.996s)\r\n-------------------------------------------------  Tx[P/s]   Tx[B/s]  Rx[P/s]   Rx[B/s]\r\nVirtualTraffic:                                      2.80    342.66     1.80    277.01\r\n    TCP:   carbonite:864 -> prism:2049               1.20    180.14     0.60    145.71\r\n    TCP:   carbonite:723 -> diamond:2049             0.80    119.29     0.40     86.47\r\n    TCP: carbonite:21291 -> glass:63281              0.40     21.62     0.40     22.42\r\n    TCP: carbonite:21291 -> glass:63280              0.40     21.62     0.40     22.42\r\nPhysicalTraffic:                                     2.80    454.75     1.80    349.07\r\n                   prism -> 192.168.0.101:41641      1.20    227.37     0.60    169.73\r\n                 diamond -> 143.110.111.222:41641    0.80    150.52     0.40    102.48\r\n                   glass -> 192.55.66.77:41641       0.80     76.86     0.80     76.86\r\n======================================================================================\r\nNodeID: uvwXyz2CNTRL\r\nLogged: 2022-10-28 15:40:00.344\r\nWindow: 2022-10-28 15:39:53.286 (4.999s)\r\n------------------------------------------------  Tx[P/s]   Tx[B/s]  Rx[P/s]   Rx[B/s]\r\nVirtualTraffic:                                    28.60    3.32Ki    46.41    5.87Ki\r\n    TCP:    prism:37500 -> glass:22                 9.20    1.45Ki    13.60    2.46Ki\r\n    TCP:    prism:49288 -> diamond:22              12.80    1.22Ki    20.80    2.03Ki\r\n    TCP:     prism:2049 -> carbonite:864            0.60    145.62     1.20    180.02\r\n    TCP:    prism:49284 -> diamond:22               1.00     88.01     2.00    236.03\r\n    TCP:    prism:49282 -> diamond:22               1.00     88.01     2.00    236.03\r\n    TCP:    prism:49278 -> diamond:22               1.00     88.01     2.00    236.03\r\n    TCP:    prism:49280 -> diamond:22               1.00     88.01     2.00    236.03\r\n    TCP:    prism:49286 -> diamond:22               1.00     88.01     1.80    193.62\r\n    ICMPv4:       prism -> diamond                  1.00     84.01     1.00     84.01\r\nPhysicalTraffic:                                   28.80    4.46Ki    46.41    7.74Ki\r\n                diamond -> 143.110.111.222:41641   18.80    2.48Ki    31.60    4.51Ki\r\n                  glass -> 64.71.111.222:41641      9.20    1.82Ki    13.60    3.01Ki\r\n              carbonite -> 192.168.0.102:41641      0.60    169.62     1.20    227.23\n</code></pre>\n<h2><a href=\"https://tailscale.com/docs/features/logging/network-flow-logs#network-flow-logs-streaming\">Network flow logs streaming</a></h2>\n<p>Log streaming lets you stream network flow logs into a security information and event management ( <a href=\"https://tailscale.com/learn/security-information-and-event-management\">SIEM</a>) system. For more information, refer to <a href=\"https://tailscale.com/docs/features/logging/log-streaming\">Log streaming</a>.</p>\n<h2><a href=\"https://tailscale.com/docs/features/logging/network-flow-logs#limitations\">Limitations</a></h2>\n<ul>\n<li>Only nodes using Tailscale v1.34 or later send networking telemetry to the Tailscale logs service.</li>\n<li>You can only access network logs using the API and as a <a href=\"https://tailscale.com/docs/features/logging/log-streaming\">streaming source</a> for SIEM systems. There is no network logs viewing functionality in the Tailscale admin console.</li>\n<li>Network flow logs are for logging, not monitoring. The admin console does not contain a live readout of the connections between nodes. Additionally, network logs don't include information on whether a node is online or idle. The logs only indicate whether there was network traffic.</li>\n<li>Network logs do not include individual packet transfers. Logs capture when connections are active, which could include multiple data flows.</li>\n<li>Tailscale only logs successful connects. If a connection attempt results in denied access, the attempt isn't logged.</li>\n<li>Traffic information at the physical layer is gathered at a slightly different time than the virtual layer, so packets flowing through the virtual layer might not precisely line up with those at the physical layer.</li>\n<li>Public IP addresses are not logged as either a destination or source. That is, a connection from your tailnet through an exit node does not log where the traffic is going, and a connection from the public internet through an exit node does not log where the traffic is returning from. To preserve privacy, Tailscale doesn't gather detailed information about individual connections.\n<ul>\n<li>If <a href=\"https://tailscale.com/docs/features/exit-nodes#destination-logging-in-network-flow-logs\">Destination Logging</a> is enabled by the administrator, the protocol, source port, and destination information are logged.</li>\n</ul>\n</li>\n<li>The user authenticated on a source or destination host is not logged. To map a node to a user, you can use the <a href=\"https://tailscale.com/api#tag/devices/GET/tailnet/%7Btailnet%7D/devices\"><code>/api/v2/tailnet/:tailnet/device</code></a> method and examine the <code>user</code> field.</li>\n<li>Network logging is performed client-side. Tailscale cannot guarantee the delivery or integrity of the client logs. Tailscale cannot fully guarantee client log latency thresholds—that is, logs are not delivered in real-time.</li>\n<li>Enabling network flow logs might result in a slight performance impact because the client does additional work to track necessary metrics. The incremental load is spread across the fleet, not concentrated on a single host.</li>\n</ul>\n<p><img src=\"https://cdn.brandfetch.io/tailscale.com/fallback/lettermark/theme/dark/h/256/w/256/icon?c=1bfwsmEH20zzEfSNTed\" alt=\"Project Logo\"></p>\n<p>Ask AI</p>\n<p>reCAPTCHA</p>\n<p>Recaptcha requires verification.</p>\n<p>protected by <strong>reCAPTCHA</strong></p>\n"}