amir20/dozzle · warning

invalid maxStart

Error message

invalid maxStart

What it means

After parsing `maxStart`, the handler validates 1 <= maxStart <= buffer.Size (500). Out-of-range values receive the fixed message "invalid maxStart" with HTTP 400 Bad Request. maxStart is 1-based and must fit within the ring buffer.

Solutions

  1. Use a 1-based integer between 1 and 500
  2. Omit maxStart when unsure; the default allows any start
  3. Derive maxStart from the buffer size of the previous response, not from container event IDs
  4. Validate 1 <= value <= 500 before sending

Example fix

// before
params.set("maxStart", String(event.id)); // id may be 0 or huge
// after
if (idx >= 1 && idx <= 500) params.set("maxStart", String(idx));
Defensive patterns

Strategy: validation

Validate before calling

if (!Number.isInteger(v) || v < 1 || v > 500) throw new Error("maxStart out of range");

Prevention

When it happens

Trigger: GET .../logs?maxStart=0 (below the 1-based minimum) or ?maxStart=501 (above buffer size 500). Negative values likewise fail.

Common situations: Clients that captured lastSeenId style indices starting at 0; sending event IDs instead of buffer indices; code assuming maxStart is 0-based; buffer resized via `min` to less than the requested maxStart.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of amir20/dozzle@d9463cbe21 (2026-09-07). Data as JSON: /api/errors/437c121f20dbad51. Report an issue: GitHub.

Appendix: source

Thrown at internal/web/logs.go:161

			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		if minimum < 0 || minimum > buffer.Size {
			http.Error(w, "minimum must be between 0 and buffer size", http.StatusBadRequest)
			return
		}
		buffer = utils.NewRingBuffer[*container.LogEvent](minimum)
	}

	maxStart := math.MaxInt
	if r.URL.Query().Has("maxStart") {
		maxStart, err = strconv.Atoi(r.URL.Query().Get("maxStart"))
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		if maxStart < 1 || maxStart > buffer.Size {
			http.Error(w, "invalid maxStart", http.StatusBadRequest)
			return
		}
	}

	levels := make(map[string]struct{})
	for _, level := range r.URL.Query()["levels"] {
		levels[level] = struct{}{}
	}

	lastSeenId := uint32(0)
	if r.URL.Query().Has("lastSeenId") {
		to = to.Add(50 * time.Millisecond)
		num, err := strconv.ParseUint(r.URL.Query().Get("lastSeenId"), 10, 32)
		if err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
		lastSeenId = uint32(num)

View on GitHub (pinned to d9463cbe21)