prometheus/node_exporter · error
invalid TCP states data: expected
Error message
invalid TCP states data: expected %d entries, found %d
What it means
The FreeBSD netstat collector reads the kernel TCP state table via sysctl and expects the returned binary buffer to contain exactly one 8-byte entry per known TCP state. If the buffer size divided by 8 does not match the length of the tcpStates name table, the collector cannot safely map entries to state names and returns this error instead of emitting wrong metrics.
Solutions
- Rebuild/run the node_exporter version that matches your FreeBSD kernel version so the tcpStates table matches the kernel's output.
- Verify the sysctl value backing this data (e.g. net.inet.tcp.states / kern IPC data) returns the expected entry count on the host.
- If a kernel version changed the state list, update the tcpStates table in collector/netstat_freebsd.go to match and file/track an upstream issue.
- Report the kernel version and the 'found' value from the error message upstream to help extend the compatibility table.
Example fix
// before (collector assumes fixed state count)
if len(data)/8 != len(tcpStates) {
return nil, fmt.Errorf("invalid TCP states data: expected %d entries, found %d", len(tcpStates), len(data)/8)
}
// after (optionally tolerate extra kernel entries by parsing only the known prefix)
if len(data)/8 < len(tcpStates) {
return nil, fmt.Errorf("invalid TCP states data: expected at least %d entries, found %d", len(tcpStates), len(data)/8)
} Defensive patterns
Strategy: validation
Validate before calling
// Before parsing, check that the sysctl buffer size matches the state table
// (this is what the collector does; if you extend it, keep the check):
// data, _ := sysctlRaw(...)
// if len(data)/8 != len(tcpStates) { /* skip TCP state metrics this scrape */ } Type guard
null
Try / catch
null
Prevention
- Pin node_exporter versions to the FreeBSD release they were built/tested against.
- After kernel upgrades, redeploy a node_exporter build matching the new kernel.
- Monitor scrape errors so a mismatch is noticed immediately.
- When porting to new FreeBSD versions, update the tcpStates table and its tests first.
When it happens
Trigger: The sysctl call returns a buffer whose length/8 differs from len(tcpStates); this happens when the kernel returns fewer or more TCP state counters than the collector's hardcoded state list (e.g. a newer/older FreeBSD kernel with a changed number of TCP states, or a truncated/partial sysctl read).
Common situations: Running node_exporter built for one FreeBSD version on a kernel with a different TCPstate count; unusual kernels or ABI drift between userland sysctl expectations and the running kernel.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Data Size mismatch
- sysctl(vm.stats.vm.v_page_size) failed
- couldn't get memory
- couldn't get sysctl
- could not retrieve CPU times
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/e7d04d5038a9fab0.
Report an issue: GitHub.
Appendix: source
Thrown at collector/netstat_freebsd.go:265
}
if len(data) < expectedSize {
return nil, errors.New("Data Size mismatch")
}
return data, nil
}
func getTCPStates() ([]uint64, error) {
// This sysctl returns an array of uint64
data, err := sysctlRaw("net.inet.tcp.states")
if err != nil {
return nil, err
}
if len(data)/8 != len(tcpStates) {
return nil, fmt.Errorf("invalid TCP states data: expected %d entries, found %d", len(tcpStates), len(data)/8)
}
states := make([]uint64, 0)
offset := 0
for range len(tcpStates) {
s := data[offset : offset+8]
offset += 8
states = append(states, binary.NativeEndian.Uint64(s))
}
return states, nil
}
type netStatCollector struct {
netStatMetric *prometheus.Desc
}
func init() {View on GitHub (pinned to 17ddd77c59)