hashicorp/nomad · error

unable to pull infra docker image %q: %w

Error message

unable to pull infra docker image %q: %w

What it means

pullInfraImage parses the configured infra_image into repo:tag before pulling. If parseDockerImage cannot parse the configured image reference, the error is wrapped as 'unable to pull infra docker image'. This check happens before any registry contact, so the failure is about the image reference format, not the pull itself.

Source

Thrown at drivers/docker/network.go:189

			// Set the network mode to none which creates a network namespace
			// with only a loopback interface.
			NetworkMode: "none",

			// Set the restart policy to unless-stopped. The pause container should
			// never not be running until Nomad issues a stop.
			//
			// https://docs.docker.com/engine/reference/run/#restart-policies---restart
			RestartPolicy: containerapi.RestartPolicy{Name: containerapi.RestartPolicyUnlessStopped},
		},
	}, nil
}

// pullInfraImage conditionally pulls the `infra_image` from the Docker registry
// only if its name uses the "latest" tag or the image doesn't already exist locally.
func (d *Driver) pullInfraImage(allocID string) error {
	repo, tag, err := parseDockerImage(d.config.InfraImage)
	if err != nil {
		return fmt.Errorf("unable to pull infra docker image %q: %w", d.config.InfraImage, err)
	}

	dockerClient, err := d.getDockerClient()
	if err != nil {
		return err
	}

	// There's a (narrow) time-of-check-time-of-use race here. If we call
	// InspectImage and then a concurrent task shutdown happens before we call
	// IncrementImageReference, we could end up removing the image, and it
	// would no longer exist by the time we get to PullImage below.
	d.coordinator.imageLock.Lock()

	if tag != "latest" {
		dockerImage, err := dockerClient.ImageInspect(d.ctx, d.config.InfraImage)
		if err != nil {
			d.logger.Debug("InspectImage failed for infra_image container pull",
				"image", d.config.InfraImage, "error", err)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Fix the infra_image value in the client config to a valid image reference, e.g. 'busybox:latest'
  2. Ensure the reference includes a parseable repo and optional tag/digest
  3. Check for unexpanded environment variables or stray quotes in the config
  4. Restart the Nomad client after correcting the configuration

Example fix

// before
infra_image = "myinfra:"
// after
infra_image = "myinfra:latest"
Defensive patterns

Strategy: validation

Validate before calling

func validImageRef(ref string) error {
    if ref == "" { return errors.New("infra_image empty") }
    if _, _, err := reference.ParseAnyReference(ref); err != nil {
        return fmt.Errorf("invalid infra_image %q: %w", ref, err)
    }
    return nil
}
// run at client startup, before allocations arrive

Prevention

When it happens

Trigger: Driver option 'infra_image' is set to a value parseDockerImage rejects (empty reference, invalid characters, malformed tag/digest), and CreateNetwork invokes pullInfraImage for an allocation needing a bridge network.

Common situations: Typo in infra_image in the client block (e.g. missing repository name, stray spaces); copying an image reference with quotes or variables unresolved; invalid registry port syntax like 'registry:5000:' with empty tag.

Related errors


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