VictoriaMetrics/VictoriaMetrics · error
cannot read int64: %w
Error message
cannot read int64: %w
What it means
Returned by vmselectRequestCtx.readInt64 when io.ReadFull fails to read the full 8 bytes of an int64 field (used by processMetricNamesUsageStats) with a non-EOF error. The cause is wrapped with %w. It means the protocol stream carrying the usage-stats request was truncated or the connection broke.
Source
Thrown at lib/vmselectapi/server.go:351
func (ctx *vmselectRequestCtx) readUint64() (uint64, error) {
ctx.sizeBuf = bytesutil.ResizeNoCopyMayOverallocate(ctx.sizeBuf, 8)
if _, err := io.ReadFull(ctx.bc, ctx.sizeBuf); err != nil {
if err == io.EOF {
return 0, err
}
return 0, fmt.Errorf("cannot read uint64: %w", err)
}
n := encoding.UnmarshalUint64(ctx.sizeBuf)
return n, nil
}
func (ctx *vmselectRequestCtx) readInt64() (int64, error) {
ctx.sizeBuf = bytesutil.ResizeNoCopyMayOverallocate(ctx.sizeBuf, 8)
if _, err := io.ReadFull(ctx.bc, ctx.sizeBuf); err != nil {
if err == io.EOF {
return 0, err
}
return 0, fmt.Errorf("cannot read int64: %w", err)
}
n := encoding.UnmarshalInt64(ctx.sizeBuf)
return n, nil
}
func (ctx *vmselectRequestCtx) readAccountIDProjectID() (uint32, uint32, error) {
accountID, err := ctx.readUint32()
if err != nil {
return 0, 0, fmt.Errorf("cannot read accountID: %w", err)
}
projectID, err := ctx.readUint32()
if err != nil {
return 0, 0, fmt.Errorf("cannot read projectID: %w", err)
}
return accountID, projectID, nil
}
// maxSearchQuerySize is the maximum size of SearchQuery packet in bytes.View on GitHub (pinned to 5079fb58f1)
Solutions
- Verify the int64 field is written as exactly 8 bytes little-endian.
- Check the wrapped cause (unexpected EOF vs reset) to distinguish truncation from connection loss.
- Match component versions across the cluster.
- Inspect LB/firewall idle-timeout settings for internal select connections.
- Retry on a fresh connection.
Defensive patterns
Strategy: try-catch
Validate before calling
// client side: fixed 8-byte encoding for int64 fields binary.LittleEndian.PutUint64(buf, uint64(int64Val))
Type guard
func isTruncatedRead(err error) bool { return errors.Is(err, io.ErrUnexpectedEOF) } Try / catch
v, err := readInt64(conn)
if err != nil {
if errors.Is(err, io.EOF) { return io.EOF }
return fmt.Errorf("failed reading int64 field: %w", err)
} Prevention
- Round-trip int64 through uint64 for little-endian encoding
- Keep cluster component versions aligned
- Add read deadlines to detect stalled connections early
- Retry usage-stats requests on a new connection
When it happens
Trigger: A client calling the metric-names usage stats endpoint over the internal vmselect protocol sends fewer than 8 bytes for the int64 field, or the connection dies mid-read.
Common situations: Hand-written protocol clients mis-sizing fields; network interruption between vminsert/vmagent and vmselect; LB or firewall dropping long-lived internal connections.
Related errors
- cannot read uint32: %w
- cannot read uint64: %w
- cannot read data size: %w
- cannot flush %q to server: %w
- cannot read message with size %d: %w; read only %d bytes
AI-assisted analysis of VictoriaMetrics/VictoriaMetrics@5079fb58f1 (2026-09-03).
Data as JSON: /api/errors/7c571f4237985e83.
Report an issue: GitHub.