hashicorp/nomad · error
first message should always be setup
Error message
first message should always be setup
What it means
The ExecStreaming gRPC handler requires the very first message on the stream to contain the Setup field (command and tty configuration). This error is returned when the client opens the stream but sends a message whose Setup is nil, or a non-setup message first.
Source
Thrown at drivers/shared/executor/grpc_server.go:178
out, exit, err := s.impl.Exec(deadline, req.Cmd, req.Args)
if err != nil {
return nil, err
}
return &proto.ExecResponse{
Output: out,
ExitCode: int32(exit),
}, nil
}
func (s *grpcExecutorServer) ExecStreaming(server proto.Executor_ExecStreamingServer) error {
msg, err := server.Recv()
if err != nil {
return fmt.Errorf("failed to receive initial message: %v", err)
}
if msg.Setup == nil {
return fmt.Errorf("first message should always be setup")
}
return s.impl.ExecStreaming(server.Context(),
msg.Setup.Command, msg.Setup.Tty,
server)
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Always send ExecTaskStreamingRequest{Setup: &proto.ExecTaskStreamingRequest_Setup{...}} as the first stream message
- Ensure client and server use the same nomad protobuf definitions (match Nomad versions)
- Validate the setup payload is populated before calling stream.Send
- Regenerate proto bindings if a custom client's generated code is stale
Example fix
// before
stream.Send(&proto.ExecTaskStreamingRequest{}) // no Setup
// after
stream.Send(&proto.ExecTaskStreamingRequest{Setup: &proto.ExecTaskStreamingRequest_Setup{Command: cmd, Tty: false}}) Defensive patterns
Strategy: validation
Validate before calling
if req.Setup == nil { return errors.New("setup must be sent first") } // client-side pre-send check Try / catch
if err := stream.Send(setupFirst); err != nil {
if strings.Contains(err.Error(), "first message should always be setup") { fix client ordering }
} Prevention
- Always make Setup the first stream message
- Keep client and server Nomad/proto versions in sync
- Regenerate proto bindings after proto changes
When it happens
Trigger: Client sends an empty ExecTaskStreamingRequest, sends an input/resize message before setup, or a client/server proto version mismatch causes Setup to be dropped.
Common situations: Hand-rolled or version-mismatched clients speaking to the executor gRPC API; upgrading Nomad agents/executors out of sync so proto fields deserialize differently; buggy custom tooling around alloc exec.
Related errors
- first message should always be setup
- failed to receive initial message: %v
- failed to receive initial message: %v
- nil response from plugin.NodeExpandVolume
- missing AllocID
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/d4cae15b2e6cd3d5.
Report an issue: GitHub.