hashicorp/nomad · error

variable must not be nil

Error message

variable must not be nil

What it means

Variables.Apply requires the request to carry a Var object describing the variable operation. If args.Var is nil, the endpoint immediately rejects the call before ACL or keyring checks. It is a basic request-shape validation error.

Source

Thrown at nomad/variables_endpoint.go:78

// Apply is used to apply a SV update request to the data store.
func (sv *Variables) Apply(args *structs.VariablesApplyRequest, reply *structs.VariablesApplyResponse) error {

	authErr := sv.srv.Authenticate(sv.ctx, args)
	if done, err := sv.srv.forward(structs.VariablesApplyRPCMethod, args, args, reply); done {
		return err
	}
	sv.srv.MeasureRPCRate("variables", structs.RateMetricWrite, args)
	if authErr != nil {
		return structs.ErrPermissionDenied
	}

	defer metrics.MeasureSince([]string{
		"nomad", "variables", "apply", string(args.Op)}, time.Now())
	// TODO: Add metrics for acquire and release if the operation is lock related

	if args.Var == nil {
		return fmt.Errorf("variable must not be nil")
	}

	// Check if the Namespace is explicitly set on the variable. If
	// not, use the RequestNamespace
	targetNS := args.Var.Namespace
	if targetNS == "" {
		targetNS = args.RequestNamespace()
		args.Var.Namespace = targetNS
	}

	if !sv.srv.peersCache.ServersMeetMinimumVersion(sv.srv.Region(), minVersionKeyring, true) {
		return fmt.Errorf("all servers must be running version %v or later to apply variables", minVersionKeyring)
	}

	// Perform the ACL resolution.
	aclObj, err := sv.srv.ResolveACL(args)
	if err != nil {
		return err

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Populate args.Var with a VariableMetadata/Variable containing path, namespace, and items
  2. Use the nomad CLI (`nomad var put`) or SDK helper which builds Var correctly
  3. Add a nil check on Var before sending the request

Example fix

// before
req := &api.VariablesApplyRequest{Op: api.VarOpSet}

// after
req := &api.VariablesApplyRequest{Op: api.VarOpSet,
    Var: &api.Variable{Path: "app/config", Namespace: "default", Items: map[string]string{"k": "v"}}}
Defensive patterns

Strategy: validation

Validate before calling

if req.Var == nil {
    return errors.New("variables apply request requires a non-nil Var")
}
if req.Var.Path == "" {
    return errors.New("variable path is required")
}

Type guard

func hasVar(r *api.VariablesApplyRequest) bool { return r != nil && r.Var != nil }

Try / catch

_, err := client.Variables().Apply(req, nil)
if err != nil && strings.Contains(err.Error(), "variable must not be nil") {
    // fix request construction before retrying
}

Prevention

When it happens

Trigger: Calling Variables Apply (nomad var put, SDK Apply) with a VariablesApplyRequest whose Var field was never set — e.g. constructing the request for a delete-style op but leaving Var nil.

Common situations: Hand-rolling API requests instead of using the CLI/SDK helpers; deserialization dropping the Var field; template code copying a request struct without initializing Var.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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