hashicorp/nomad · error

only one storage block is allowed

Error message

only one storage block is allowed

What it means

HCL validation error in parseStorageResource for quota specifications: more than one storage block was declared, but a quota's storage section accepts exactly one block listing variables/host_volumes limits.

Source

Thrown at command/quota_apply.go:332

	// Parse per-node-pool limit
	if o := listVal.Filter("node_pool"); len(o.Items) > 0 {
		result.NodePools = make([]*api.NodePoolLimit, 0)
		if err := parseNodePoolLimit(&result.NodePools, o); err != nil {
			return multierror.Prefix(err, "node pool ->")
		}
	}

	return nil
}

func parseStorageResource(storageBlocks *ast.ObjectList) (*api.QuotaStorageResources, error) {
	switch len(storageBlocks.Items) {
	case 0:
		return nil, nil
	case 1:
	default:
		return nil, errors.New("only one storage block is allowed")
	}
	block := storageBlocks.Items[0]
	valid := []string{"variables", "host_volumes"}
	if err := helper.CheckHCLKeys(block.Val, valid); err != nil {
		return nil, err
	}

	var m map[string]any
	if err := hcl.DecodeObject(&m, block.Val); err != nil {
		return nil, err
	}

	variablesLimit, err := parseQuotaMegabytes(m["variables"])
	if err != nil {
		return nil, fmt.Errorf("invalid variables limit: %v", err)
	}
	hostVolumesLimit, err := parseQuotaMegabytes(m["host_volumes"])
	if err != nil {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Edit the HCL file to keep exactly one storage block, merging keys into it.
  2. Search the file for repeated `storage {` occurrences and deduplicate.
  3. Validate the merged file with `nomad quota apply` on a scratch copy before applying to production.

Example fix

// before
storage {
  variables { enabled = true }
}
storage {
  host_volumes { enabled = true }
}
// after
storage {
  variables     { enabled = true }
  host_volumes  { enabled = true }
}
Defensive patterns

Strategy: validation

Validate before calling

import "github.com/hashicorp/hcl/v2/hclsimple"
// or pre-parse:
func countStorageBlocks(hclSrc string) int {
    return strings.Count(hclSrc, "storage {")
}
if countStorageBlocks(src) > 1 {
    return errors.New("quota HCL has more than one storage block")
}

Try / catch

if err := quotaApply(); err != nil && strings.Contains(err.Error(), "only one storage block is allowed") {
    // deduplicate storage blocks in the HCL file and retry
}

Prevention

When it happens

Trigger: Running `nomad quota apply <name> <file.hcl>` where the HCL file contains duplicate `storage { ... }` blocks.

Common situations: Merging quota files by concatenation, copy-pasting blocks and forgetting to remove the old one, templating bugs that emit the block twice.

Related errors


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