hashicorp/nomad · error

format error

Error message

format error: %v

What it means

When `nomad plugin status` with CSI plugins is run with -json or -template, csiFormatPlugins renders the plugin list via the shared Format helper. If JSON marshaling or template execution fails, the error is wrapped as "format error".

Solutions

  1. Test the template with plain output first (`nomad plugin status <id>`) to confirm the data shape, then fix template field names.
  2. Validate template syntax — missing {{end}}, bad pipelines, undefined functions.
  3. Use -json alone to see the exact structure before writing a template.
  4. Keep the wrapped error text after "format error:" to pinpoint the template line.

Example fix

// before
nomad plugin status -template '{{range .Plugins}}{{.ID}}{{end}}'

// after
nomad plugin status -template '{{range .}}{{.ID}}{{end}}'
Defensive patterns

Strategy: validation

Validate before calling

// render with -json first to confirm data shape before templating
const data = execSync('nomad plugin status -json').toString();
const plugins = JSON.parse(data); // must be an array of CSIPlugin
if (!Array.isArray(plugins)) throw new Error('expected plugin list');

Try / catch

try { out = csiFormatPlugins(plugs) } catch (e) { if (String(e).startsWith('format error')) { console.error('Template invalid for plugin list; test with -json first:', e.message); } throw e; }

Prevention

When it happens

Trigger: Running `nomad plugin status -json` or `-template '...'` where the template has invalid syntax, references fields that don't exist on []api.CSIPlugin, or JSON output cannot be produced.

Common situations: Typos in template field paths (e.g. {{.Plugins}} when the data is a plain list), wrong template functions, or copying Consul/Vault templates that expect different data shapes.

Related errors


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

Appendix: source

Thrown at command/plugin_status_csi.go:90

	str, err := c.csiFormatPlugin(plug)
	if err != nil {
		c.Ui.Error(fmt.Sprintf("Error formatting plugin: %s", err))
		return 1
	}

	c.Ui.Output(str)
	return 0
}

func (c *PluginStatusCommand) csiFormatPlugins(plugs []*api.CSIPluginListStub) (string, error) {
	// Sort the output by quota name
	sort.Slice(plugs, func(i, j int) bool { return plugs[i].ID < plugs[j].ID })

	if c.json || len(c.template) > 0 {
		out, err := Format(c.json, c.template, plugs)
		if err != nil {
			return "", fmt.Errorf("format error: %v", err)
		}
		return out, nil
	}

	rows := make([]string, len(plugs)+1)
	rows[0] = "ID|Provider|Controllers Healthy/Expected|Nodes Healthy/Expected"
	for i, p := range plugs {
		rows[i+1] = fmt.Sprintf("%s|%s|%d/%d|%d/%d",
			limit(p.ID, c.length),
			p.Provider,
			p.ControllersHealthy,
			p.ControllersExpected,
			p.NodesHealthy,
			p.NodesExpected,
		)
	}
	return formatList(rows), nil
}

View on GitHub (pinned to 482b49bf1a)