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
- Fix the infra_image value in the client config to a valid image reference, e.g. 'busybox:latest'
- Ensure the reference includes a parseable repo and optional tag/digest
- Check for unexpanded environment variables or stray quotes in the config
- 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
- Validate infra_image in config management before shipping to clients
- Always include repo and tag (e.g. busybox:1.36)
- Avoid unexpanded template variables in image references
- Smoke-test client config changes on one node first
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
- does not match registry specification
- failed to parse 'image_delay' duration: %v
- failed to parse 'period' duration: %v
- failed to parse 'creation_grace' duration: %v
- creation_grace is less than minimum, %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/24537c2cfaa32ac0.
Report an issue: GitHub.