valyala/fasthttp · warning

the start position of byte range cannot exceed the end…

Error message

the start position of byte range cannot exceed the end position. byte range %q

What it means

After parsing start and end offsets and clamping end to contentLength-1, fasthttp requires end >= start. A range like bytes=500-100 where 500 > the (clamped) end is unsatisfiable and returns this error.

Solutions

  1. Fix the client to always send end >= start (inclusive byte positions)
  2. Validate before sending: if start > end, send the full GET or a corrected range
  3. If the end was clamped by server-side contentLength, your start is also stale — re-fetch file size/ETag and restart
  4. For direct calls, check endPos >= startPos before invoking ParseByteRange

Example fix

// before
Range: bytes=500-100
// after
start, end = min(start, end), max(start, end)
Range: bytes=100-500
Defensive patterns

Strategy: validation

Validate before calling

if start > end {
    start, end = end, start // or reject the header
}

Type guard

func rangeOrdered(start, end int) bool { return start <= end }

Try / catch

start, end, err := fs.ParseByteRange(hdr, cl)
if err != nil && strings.Contains(err.Error(), "cannot exceed the end position") {
    return 416
}

Prevention

When it happens

Trigger: Client sends an inverted range (bytes=100-50); end position exceeded contentLength and was clamped below an already-too-large start (e.g. bytes=900-9999 for a 1000-byte body becomes end=999 < start=900); direct ParseByteRange calls with inverted values.

Common situations: Buggy range-splitting code in download managers (chunk boundaries computed wrong); clients reusing offsets across differently sized files; off-by-one when converting 'first byte + length' to inclusive start/end.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/7d1d7589aaf39942. Report an issue: GitHub.

Appendix: source

Thrown at fs.go:1529

		return 0, 0, err
	}
	if startPos >= contentLength {
		return 0, 0, fmt.Errorf("the start position of byte range cannot exceed %d. byte range %q", contentLength-1, byteRange)
	}

	b = b[n+1:]
	if len(b) == 0 {
		return startPos, contentLength - 1, nil
	}

	if endPos, err = ParseUint(b); err != nil {
		return 0, 0, err
	}
	if endPos >= contentLength {
		endPos = contentLength - 1
	}
	if endPos < startPos {
		return 0, 0, fmt.Errorf("the start position of byte range cannot exceed the end position. byte range %q", byteRange)
	}
	return startPos, endPos, nil
}

func (h *fsHandler) openIndexFile(ctx *RequestCtx, dirPath string, mustCompress bool, fileEncoding string) (*fsFile, error) {
	for _, indexName := range h.indexNames {
		indexFilePath := indexName
		if dirPath != "" {
			indexFilePath = dirPath + "/" + indexName
		}

		ff, err := h.openFSFile(indexFilePath, mustCompress, fileEncoding)
		if err == nil {
			return ff, nil
		}
		if mustCompress && err == errNoCreatePermission {
			ctx.Logger().Printf("insufficient permissions for saving compressed file for %q. Serving uncompressed file. "+
				"Allow write access to the directory with this file in order to improve fasthttp performance", indexFilePath)

View on GitHub (pinned to c96f600972)