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

  1. Verify the int64 field is written as exactly 8 bytes little-endian.
  2. Check the wrapped cause (unexpected EOF vs reset) to distinguish truncation from connection loss.
  3. Match component versions across the cluster.
  4. Inspect LB/firewall idle-timeout settings for internal select connections.
  5. 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

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


AI-assisted analysis of VictoriaMetrics/VictoriaMetrics@5079fb58f1 (2026-09-03). Data as JSON: /api/errors/7c571f4237985e83. Report an issue: GitHub.