docker/cli · error

failed to execute template

Error message

failed to execute template: %w

What it means

Returned by list.go:95 when a parsed --format template executes against a dry-run optionsProcessor (io.Discard) and fails. Parsing succeeded but execution revealed a problem, e.g. referencing a field that errors during the dry-run pass.

Solutions

  1. Simplify the template to isolate the failing field/function.
  2. Confirm each field is valid for the container context (use docker ps --format '{{json .}}' to inspect).
  3. Avoid calling functions with argument shapes the template engine rejects.

Example fix

# inspect available fields
docker ps --format '{{json .}}'

# then build the template using only valid fields

# before
docker ps --format '{{.NonExistentField}}'
# after
docker ps --format '{{.Names}}'
Defensive patterns

Strategy: validation

Validate before calling

// Parse then execute against a throwaway context to catch execution errors:
tmpl, err := templates.Parse(format)
if err != nil { return err }
if err := tmpl.Execute(io.Discard, formatter.NewContainerContext()); err != nil {
    return fmt.Errorf("template executes but fails: %w", err)
}

Try / catch

// Execution errors are usually semantic; simplify the template.
if err != nil && strings.Contains(err.Error(), "failed to execute template") {
    /* fall back to a minimal valid template */
}

Prevention

When it happens

Trigger: A `docker ps --format` template that parses fine but errors at execution time during the pre-flight dry run, such as calling a template function in a way that panics/errors when invoked on the container context object.

Common situations: A template field or function that is valid syntactically but invalid semantically for the container formatter context, or a custom function with wrong arguments.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/d4524fd8a98dc334. Report an issue: GitHub.

Appendix: source

Thrown at cli/command/container/list.go:95

	}

	if options.nLatest && options.last == -1 {
		listOptions.Limit = 1
	}

	// always validate template when `--format` is used, for consistency
	if len(options.format) > 0 {
		tmpl, err := templates.Parse(options.format)
		if err != nil {
			return client.ContainerListOptions{}, fmt.Errorf("failed to parse template: %w", err)
		}

		optionsProcessor := formatter.NewContainerContext()

		// This shouldn't error out but swallowing the error makes it harder
		// to track down if preProcessor issues come up.
		if err := tmpl.Execute(io.Discard, optionsProcessor); err != nil {
			return client.ContainerListOptions{}, fmt.Errorf("failed to execute template: %w", err)
		}

		// if `size` was not explicitly set to false (with `--size=false`)
		// and `--quiet` is not set, request size if the template requires it
		if !options.quiet && !listOptions.Size && !options.sizeChanged {
			// The --size option isn't set, but .Size may be used in the template.
			// Parse and execute the given template to detect if the .Size field is
			// used. If it is, then automatically enable the --size option. See #24696
			//
			// Only requesting container size information when needed is an optimization,
			// because calculating the size is a costly operation.

			if _, ok := optionsProcessor.FieldsUsed["Size"]; ok {
				listOptions.Size = true
			}
		}
	}

View on GitHub (pinned to 4f84911bfe)