hashicorp/nomad · error
variables are limited to 64KiB in total size
Error message
variables are limited to 64KiB in total size
What it means
VariableDecrypted.ValidateForLock rejects any lock-related variable whose serialized Items exceed the 64KiB (maxVariableSize) limit. Nomad caps the total size of a variable's key/value payload so it stays within raft and RPC size budgets. When the payload is too large, the sentinel errQuotaExhausted is returned instead of storing the variable.
Source
Thrown at nomad/structs/variables.go:75
minVariableLockTTL = 10 * time.Second
maxVariableLockTTL = 24 * time.Hour
// defaultLockTTL is the default value used to maintain a lock before it needs to
// be renewed. The actual value comes from the experience with Consul.
defaultLockTTL = 15 * time.Second
// defaultLockDelay is the default a lock will be blocked after the TTL
// went by without any renews. It is intended to prevent split brain situations.
// The actual value comes from the experience with Consul.
defaultLockDelay = 15 * time.Second
)
var (
errNoPath = errors.New("missing path")
errNoNamespace = errors.New("missing namespace")
errNoLock = errors.New("missing lock ID")
errWildCardNamespace = errors.New("can not target wildcard (\"*\")namespace")
errQuotaExhausted = errors.New("variables are limited to 64KiB in total size")
errNegativeDelayOrTTL = errors.New("Lock delay and TTL must be positive")
errInvalidTTL = errors.New("TTL must be between 10 seconds and 24 hours")
)
// VariableMetadata is the metadata envelope for a Variable, it is the list
// object and is shared data between an VariableEncrypted and a
// VariableDecrypted object.
type VariableMetadata struct {
Namespace string
Path string
// Lock represents a variable which is used for locking functionality.
Lock *VariableLock `json:",omitempty"`
CreateIndex uint64
CreateTime int64
ModifyIndex uint64
ModifyTime int64View on GitHub (pinned to 482b49bf1a)
Solutions
- Reduce the payload: split the data across multiple variables under different paths so each stays under 64KiB.
- Remove unneeded keys or compress/trim large values (store a path/URL to the data instead of the data itself).
- Check vd.Items.Size() before calling the API and reject or split oversized payloads in your tooling.
Example fix
// before
variable.Items["big-config"] = string(largeJSONBlob) // > 64KiB total
err := variable.ValidateForLock()
// after
if variable.Items.Size() > 60*1024 {
parts := splitPayload(largeJSONBlob, 32*1024)
for i, p := range parts {
sv := variable.Copy()
sv.Path = fmt.Sprintf("%s/part%d", variable.Path, i)
sv.Items = map[string]string{"data": p}
}
} Defensive patterns
Strategy: validation
Validate before calling
func variableFits(v structs.VariableDecrypted) bool {
return v.Items.Size() <= structs.MaxVariableSize // 64KiB
} Try / catch
if err := vd.ValidateForLock(); err != nil {
if err.Error() == "variables are limited to 64KiB in total size" {
return fmt.Errorf("variable %q exceeds 64KiB; split it into smaller variables", vd.Path)
}
return err
} Prevention
- Check Items.Size() in tooling before submitting variable writes.
- Split large configs across multiple variable paths.
- Store references (paths, URLs) instead of raw large blobs.
When it happens
Trigger: Calling ValidateForLock on a VariableDecrypted whose vd.Items.Size() > maxVariableSize (64KiB); e.g. creating or updating a lock variable whose key/value data totals more than 65536 bytes.
Common situations: Storing large config blobs, certificates, or many keys in a single variable; migrating secrets from Vault/consul-template files verbatim into one Nomad variable; accidentally embedding binary data instead of references.
Related errors
- missing path
- missing namespace
- missing lock ID
- can not target wildcard ("*")namespace
- Lock delay and TTL must be positive
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/f9a38664684e6463.
Report an issue: GitHub.