hashicorp/nomad · warning

must provide log type (stdout/stderr)

Error message

must provide log type (stdout/stderr)

What it means

logTypeNotPresentErr is a sentinel error for log requests whose Type is neither "stdout" nor "stderr". The client maps this field onto a filename variant, so anything else is rejected. Returned with HTTP 400 Bad Request from the logs endpoints.

Solutions

  1. Set the type parameter to exactly "stdout" or "stderr" (lowercase)
  2. In code, normalize/validate the log type before the request: switch t { case "stdout", "stderr": ... default: reject }
  3. If you need both streams, issue two requests rather than a combined value

Example fix

// before
req := &cstructs.FsLogsRequest{AllocID: id, Task: "web", Type: "out"}
// after
req := &cstructs.FsLogsRequest{AllocID: id, Task: "web", Type: "stdout"}
Defensive patterns

Strategy: validation

Validate before calling

switch logType {
case "stdout", "stderr":
    // ok
default:
    return fmt.Errorf("log type must be exactly \"stdout\" or \"stderr\", got %q", logType)
}

Type guard

func isValidLogType(t string) bool {
    return t == "stdout" || t == "stderr"
}

Try / catch

r, err := client.AllocFS().Logs(alloc, task, "", false, logType, "end", 0, ctx.Done(), nil)
if err != nil && strings.Contains(err.Error(), "must provide log type") {
    log.Printf("bad log type %q, falling back to stdout", logType)
    return client.AllocFS().Logs(alloc, task, "", false, "stdout", "end", 0, ctx.Done(), nil)
}

Prevention

When it happens

Trigger: Calling logs/Logs with a req.Type value outside {"stdout", "stderr"} — empty string, "out", "1", "both", etc.

Common situations: CLI/API callers using abbreviations like 'out' or numeric fd identifiers; template variables defaulting to empty; mixing up the parameter name (passing log level or file name where type is expected).

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


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

Appendix: source

Thrown at client/fs_endpoint.go:36

	"syscall"
	"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)