VictoriaMetrics/VictoriaMetrics · error

cannot read accountID: %w

Error message

cannot read accountID: %w

What it means

Wrapping error from vmselectRequestCtx.readAccountIDProjectID when its first readUint32 call (accountID) fails. It chains the underlying error from reading the 4-byte accountID field. This means the tenant identifier at the start of the request packet could not be read — the stream was truncated or the connection broke.

Source

Thrown at lib/vmselectapi/server.go:360

	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.
// see https://github.com/VictoriaMetrics/VictoriaMetrics/issues/5154#issuecomment-1757216612
const maxSearchQuerySize = 5 * 1024 * 1024

func (ctx *vmselectRequestCtx) readSearchQuery() error {
	if err := ctx.readDataBufBytes(maxSearchQuerySize); err != nil {
		return fmt.Errorf("cannot read searchQuery: %w", err)
	}
	tail, err := ctx.sq.Unmarshal(ctx.dataBuf)
	if err != nil {

View on GitHub (pinned to 5079fb58f1)

Solutions

  1. Ensure the client writes accountID (4 bytes LE) as the first field of the request packet.
  2. Verify network path stability between the caller and vmselect.
  3. Check the wrapped error for the concrete cause.
  4. Use /proc/<pid>/limits or connection logs to rule out abrupt disconnects; retry on new connection.
  5. Align component versions.

Example fix

// before (tenant prefix omitted)
writeSearchQuery(conn, sq)
// after
writeUint32(conn, accountID)
writeUint32(conn, projectID)
writeSearchQuery(conn, sq)
Defensive patterns

Strategy: validation

Validate before calling

// validate tenant prefix exists before sending packet
if !packetHasTenantPrefix(buf) {
    return errors.New("internal select requests must start with accountID+projectID")
}

Try / catch

accountID, projectID, err := readAccountIDProjectID(conn)
if err != nil {
    return fmt.Errorf("tenant header read failed: %w", err)
}

Prevention

When it happens

Trigger: processTagValueSuffixes or processSeriesCount receives a packet shorter than the initial 4-byte accountID, or the connection errors while reading it.

Common situations: Clients omitting the accountID/projectID prefix required by the internal protocol (default single-tenant setups forgetting to write tenant IDs); truncated writes; dropped connections.

Related errors


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