hashicorp/nomad · warning
origin must be start or end
Error message
origin must be start or end
What it means
invalidOrigin is a sentinel error for file-stream and log requests whose Origin field is not "start" or "end". Origin controls whether streaming begins at the beginning of the file or at the end (follow mode). Invalid values are rejected with HTTP 400 before any file access.
Source
Thrown at client/fs_endpoint.go:37
"time"
metrics "github.com/hashicorp/go-metrics/compat"
"github.com/hashicorp/go-msgpack/v2/codec"
"github.com/hpcloud/tail/watch"
"github.com/hashicorp/nomad/acl"
"github.com/hashicorp/nomad/client/allocdir"
sframer "github.com/hashicorp/nomad/client/lib/streamframer"
cstructs "github.com/hashicorp/nomad/client/structs"
"github.com/hashicorp/nomad/nomad/structs"
)
var (
allocIDNotPresentErr = fmt.Errorf("must provide a valid alloc id")
pathNotPresentErr = fmt.Errorf("must provide a file path")
taskNotPresentErr = fmt.Errorf("must provide task name")
logTypeNotPresentErr = fmt.Errorf("must provide log type (stdout/stderr)")
invalidOrigin = fmt.Errorf("origin must be start or end")
)
const (
// streamFramesBuffer is the number of stream frames that will be buffered
// before back pressure is applied on the stream framer.
streamFramesBuffer = 32
// streamFrameSize is the maximum number of bytes to send in a single frame
streamFrameSize = 64 * 1024
// streamHeartbeatRate is the rate at which a heartbeat will occur to detect
// a closed connection without sending any additional data
streamHeartbeatRate = 1 * time.Second
// streamBatchWindow is the window in which file content is batched before
// being flushed if the frame size has not been hit.
streamBatchWindow = 200 * time.Millisecond
View on GitHub (pinned to 482b49bf1a)
Solutions
- Use only "start" or "end" (lowercase) for the origin parameter, or omit it entirely to get the default
- For tail/follow behavior use origin=end; for full history use origin=start
- Validate/normalize the value in your client before sending: strings.ToLower + whitelist check
Example fix
// before GET /v1/client/fs/logs/<alloc>?task=web&type=stdout&origin=beginning // after GET /v1/client/fs/logs/<alloc>?task=web&type=stdout&origin=start
Defensive patterns
Strategy: validation
Validate before calling
if origin == "" {
origin = "start"
}
if origin != "start" && origin != "end" {
return fmt.Errorf("origin must be \"start\" or \"end\", got %q", origin)
} Type guard
func isValidOrigin(o string) bool {
return o == "" || o == "start" || o == "end"
} Try / catch
r, err := client.AllocFS().Logs(alloc, task, "", false, "stdout", origin, 0, ctx.Done(), nil)
if err != nil && strings.Contains(err.Error(), "origin must be start or end") {
log.Printf("invalid origin %q, using \"start\"", origin)
return client.AllocFS().Logs(alloc, task, "", false, "stdout", "start", 0, ctx.Done(), nil)
} Prevention
- Expose only two UI options (Beginning / Follow) mapped to "start"/"end"
- Normalize and lowercase user input before setting the origin parameter
- Default to empty origin (server defaults to "start") rather than inventing values
When it happens
Trigger: Calling stream, logs, Stream, or Logs with req.Origin set to anything other than "start", "end", or empty (empty is defaulted to "start") — e.g. origin=middle or origin=top.
Common situations: Hand-rolled HTTP clients guessing valid values ('beginning', 'tail'); UI passing localized or free-text offset options; casing mistakes like Origin="Start".
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- must provide task name
- must provide log type (stdout/stderr)
- missing policy name
- Unknown log level
- command is not present
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/8301d350210bf59c.
Report an issue: GitHub.