hashicorp/nomad · error

error parsing offset: %v

Error message

error parsing offset: %v

What it means

The FileReadAtRequest HTTP handler (fs file read API) parses the required 'offset' query parameter as a base-10 int64. A missing or non-numeric offset makes strconv.ParseInt fail, and the error is wrapped and returned, rejecting the file read request.

Source

Thrown at command/agent/fs_endpoint.go:151

	return reply.Info, nil
}

func (s *HTTPServer) FileReadAtRequest(resp http.ResponseWriter, req *http.Request) (any, error) {
	var allocID, path string
	var offset, limit int64
	var err error

	q := req.URL.Query()

	if allocID = strings.TrimPrefix(req.URL.Path, "/v1/client/fs/readat/"); allocID == "" {
		return nil, allocIDNotPresentErr
	}
	if path = q.Get("path"); path == "" {
		return nil, fileNameNotPresentErr
	}

	if offset, err = strconv.ParseInt(q.Get("offset"), 10, 64); err != nil {
		return nil, fmt.Errorf("error parsing offset: %v", err)
	}

	// Parse the limit
	if limitStr := q.Get("limit"); limitStr != "" {
		if limit, err = strconv.ParseInt(limitStr, 10, 64); err != nil {
			return nil, fmt.Errorf("error parsing limit: %v", err)
		}
	}

	// Create the request arguments
	fsReq := &cstructs.FsStreamRequest{
		AllocID:   allocID,
		Path:      path,
		Offset:    offset,
		Origin:    "start",
		Limit:     limit,
		PlainText: true,
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Always pass a base-10 integer offset query parameter, including 0: ?path=...&offset=0.
  2. Coerce offsets with strconv/parseInt in client code before building the URL.
  3. Strip units/fractions — send bytes as plain int64.
  4. Use the official Nomad Go API client (AllocFS.ReadAt) instead of raw HTTP calls.

Example fix

// before
GET /v1/client/fs/readat?alloc-id=...&path=/alloc/logs/app.stdout.0
// after
GET /v1/client/fs/readat?alloc-id=...&path=/alloc/logs/app.stdout.0&offset=0&limit=100000
Defensive patterns

Strategy: validation

Validate before calling

function buildReadAtURL(allocID, path, offset = 0, limit) {
  if (!Number.isInteger(offset) || offset < 0) {
    throw new TypeError(`offset must be a non-negative integer, got ${offset}`)
  }
  const q = new URLSearchParams({ 'alloc-id': allocID, path, offset: String(offset) })
  if (limit != null) q.set('limit', String(limit))
  return `/v1/client/fs/readat?${q}`
}

Type guard

function isInt64(n) {
  return Number.isInteger(n) && n >= 0 && n <= Number.MAX_SAFE_INTEGER
}

Try / catch

resp, err := http.Get(u)
// server-side response handling on caller:
if strings.Contains(errMsg, "error parsing offset") {
  retry with offset as plain base-10 integer string
}

Prevention

When it happens

Trigger: Calling GET /v1/client/fs/readat with offset absent or set to a non-integer (offset=abc, offset=, offset=1.5) — note the empty-string check earlier only guards 'path', so offset="" also fails here.

Common situations: Hand-rolled scripts hitting the filesystem API omitting offset; passing byte counts with units like '10KB'; floating-point offsets from JSON-derived code; forgetting URL encoding.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/f7b528fa4f204736. Report an issue: GitHub.