hashicorp/nomad · error

no node events given

Error message

no node events given

What it means

The client EmitEvents RPC requires at least one node event in the request. Node.EmitEvents returns this error immediately when args.NodeEvents is empty. It is a guard against no-op event-emission RPCs from clients.

Source

Thrown at nomad/node_endpoint.go:1981

	if err != nil {
		return nil, 0, err
	}
	return evalIDs, evalIndex, nil
}

func (n *Node) EmitEvents(args *structs.EmitNodeEventsRequest, reply *structs.EmitNodeEventsResponse) error {
	aclObj, err := n.srv.AuthenticateClientOnly(n.ctx, args)
	if done, err := n.srv.forward("Node.EmitEvents", args, args, reply); done {
		return err
	}
	n.srv.MeasureRPCRate("node", structs.RateMetricWrite, args)
	if err != nil {
		return structs.ErrPermissionDenied
	}
	defer metrics.MeasureSince([]string{"nomad", "client", "emit_events"}, time.Now())

	if len(args.NodeEvents) == 0 {
		return fmt.Errorf("no node events given")
	}

	callerNodeID := auth.AuthenticatedNodeID(args.GetIdentity())
	if callerNodeID == "" {
		return structs.ErrPermissionDenied
	}

	for nodeID, events := range args.NodeEvents {
		if len(events) == 0 {
			return fmt.Errorf("no node events given for node %q", nodeID)
		}

		node, err := n.srv.State().NodeByID(nil, nodeID)
		if err != nil {
			return err
		}
		if node == nil || !aclObj.AllowClientOp(node.NodePool) {
			return structs.ErrPermissionDenied

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Skip the RPC call when the batch of events is empty (check len(events) == 0 before calling)
  2. Fix the batching logic so a flush only happens when at least one event was collected
  3. If writing a driver/plugin, ensure event delivery only invokes the event hook with real events

Example fix

// before
srv.Node().EmitEvents(events) // events may be empty
// after
if len(events) > 0 {
    srv.Node().EmitEvents(events)
}
Defensive patterns

Strategy: validation

Validate before calling

if len(args.NodeEvents) == 0 {
    return nil // skip EmitEvents call entirely
}

Type guard

func hasNodeEvents(events map[string][]*structs.NodeEvent) bool {
    for _, evs := range events {
        if len(evs) > 0 { return true }
    }
    return false
}

Try / catch

err := client.Nodes().EmitEvents(args)
if err != nil && strings.Contains(err.Error(), "no node events given") {
    // treat as benign: drop the empty batch
}

Prevention

When it happens

Trigger: A Nomad client (or any caller authenticated as a node) sends Node.EmitEvents with an empty or nil NodeEvents map.

Common situations: Client plugin or driver code that batch-accumulates events but flushes an empty batch (e.g. a ticker firing with no events collected); custom tooling calling the emit_events endpoint directly.

Related errors


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