hashicorp/nomad · error

variable quota insert failed: %v

Error message

variable quota insert failed: %v

What it means

This error is returned by varSetTxn when inserting/updating the namespace's variables quota usage row (TableVariablesQuotas) into the memdb state store fails. The transaction cannot record the new quota consumption, so the variable write is aborted and an ErrorResponse is produced. It wraps the underlying memdb insert error (e.g. transaction already aborted, invalid object).

Source

Thrown at nomad/state/state_store_variables.go:288

	if quotaChange > 0 {
		quotaUsed.Size += quotaChange
	} else if quotaChange < 0 {
		quotaUsed.Size -= min(quotaUsed.Size, -quotaChange)
	}

	err = s.enforceVariablesQuota(idx, tx, sv.Namespace, quotaChange)
	if err != nil {
		return req.ErrorResponse(idx, err)
	}

	// we check enforcement above even if there's no change because another
	// namespace may have used up quota to make this no longer valid, but we
	// only update the table if this namespace has changed
	if quotaChange != 0 {
		quotaUsed.ModifyIndex = idx
		if err := tx.Insert(TableVariablesQuotas, quotaUsed); err != nil {
			return req.ErrorResponse(idx, fmt.Errorf("variable quota insert failed: %v", err))
		}
	}

	if err := tx.Insert(tableIndex,
		&IndexEntry{TableVariables, idx}); err != nil {
		return req.ErrorResponse(idx, fmt.Errorf("failed updating variable index: %s", err))
	}

	return req.SuccessResponse(idx, &sv.VariableMetadata)
}

// VarDelete is used to delete a single variable in the
// the state store.
func (s *StateStore) VarDelete(msgType structs.MessageType, idx uint64, req *structs.VarApplyStateRequest) *structs.VarApplyStateResponse {
	tx := s.db.WriteTxnMsgT(msgType, idx)
	defer tx.Abort()

	// Perform the actual delete

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Inspect the wrapped error (%v) to identify the memdb failure cause
  2. Retry the VarSet request — the write is transactional and safely aborted, so retrying is safe
  3. Verify state store integrity (restore from a known-good snapshot if corruption is suspected)
  4. Upgrade Nomad if the wrapped error points to a known memdb bug

Example fix

// before
return req.ErrorResponse(idx, fmt.Errorf("variable quota insert failed: %v", err))
// after
// add context for operators
return req.ErrorResponse(idx, fmt.Errorf("variable quota insert failed (namespace=%s): %w", sv.Namespace, err))
Defensive patterns

Strategy: retry

Try / catch

resp, err := client.Variables().Create(var)
if err != nil && strings.Contains(err.Error(), "variable quota insert failed") {
    // transient state-store failure; retry with backoff
    resp, err = backoff.Retry(func() (*vars.VariableWriteResponse, error) { return client.Variables().Create(var) })
}

Prevention

When it happens

Trigger: Calling VarSet, VarSetCAS (varSetCASTxn) or VarLockAcquire for a variable in a namespace where quotaChanged != 0 (quota tracked and size changed) and the tx.Insert(TableVariablesQuotas, quotaUsed) call fails — typically due to an aborted/invalid write txn, a corrupt or wrong-type quota row, or an internal memdb error.

Common situations: State store internals failing during heavy write load; Raft apply path applying a variable write while the memdb transaction is in a bad state; corrupted state store after snapshot restore; developer bugs introducing objects of unexpected type into TableVariablesQuotas.

Related errors


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