{"record":{"id":"d4cae15b2e6cd3d5","repo":"hashicorp/nomad","slug":"first-message-should-always-be-setup","errorCode":null,"errorMessage":"first message should always be setup","messagePattern":"first message should always be setup","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/shared/executor/grpc_server.go","lineNumber":178,"sourceCode":"\tout, exit, err := s.impl.Exec(deadline, req.Cmd, req.Args)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &proto.ExecResponse{\n\t\tOutput:   out,\n\t\tExitCode: int32(exit),\n\t}, nil\n}\n\nfunc (s *grpcExecutorServer) ExecStreaming(server proto.Executor_ExecStreamingServer) error {\n\tmsg, err := server.Recv()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to receive initial message: %v\", err)\n\t}\n\n\tif msg.Setup == nil {\n\t\treturn fmt.Errorf(\"first message should always be setup\")\n\t}\n\n\treturn s.impl.ExecStreaming(server.Context(),\n\t\tmsg.Setup.Command, msg.Setup.Tty,\n\t\tserver)\n}\n","sourceCodeStart":160,"sourceCodeEnd":185,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/drivers/shared/executor/grpc_server.go#L160-L185","documentation":"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.","triggerScenarios":"Client sends an empty ExecTaskStreamingRequest, sends an input/resize message before setup, or a client/server proto version mismatch causes Setup to be dropped.","commonSituations":"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.","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"],"exampleFix":"// before\nstream.Send(&proto.ExecTaskStreamingRequest{}) // no Setup\n// after\nstream.Send(&proto.ExecTaskStreamingRequest{Setup: &proto.ExecTaskStreamingRequest_Setup{Command: cmd, Tty: false}})","handlingStrategy":"validation","validationCode":"if req.Setup == nil { return errors.New(\"setup must be sent first\") } // client-side pre-send check","typeGuard":null,"tryCatchPattern":"if err := stream.Send(setupFirst); err != nil {\n    if strings.Contains(err.Error(), \"first message should always be setup\") { fix client ordering }\n}","preventionTips":["Always make Setup the first stream message","Keep client and server Nomad/proto versions in sync","Regenerate proto bindings after proto changes"],"tags":["grpc","streaming","protocol"],"backgroundTag":"grpc-protocol-violation","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}