hashicorp/nomad · error
unable to create local docker image %q: %w
Error message
unable to create local docker image %q: %w
What it means
createImage wraps any failure from parseDockerImage when splitting the task's docker image into repository and tag. It means the image string itself could not be parsed into a valid repo:tag reference before any registry interaction. The wrapped error typically indicates a malformed image reference (e.g. invalid characters or empty name).
Source
Thrown at drivers/docker/driver.go:625
if attempted < 5 {
attempted++
backoff = helper.Backoff(50*time.Millisecond, time.Minute, attempted)
time.Sleep(backoff)
goto START
}
return nstructs.NewRecoverableError(startErr, true)
}
return recoverableErrTimeouts(startErr)
}
// createImage creates a docker image either by pulling it from a registry or by
// loading it from the file system
func (d *Driver) createImage(task *drivers.TaskConfig, driverConfig *TaskConfig, client *client.Client) (string, string, error) {
image := driverConfig.Image
repo, tag, err := parseDockerImage(image)
if err != nil {
return "", "", fmt.Errorf("unable to create local docker image %q: %w", image, err)
}
// We're going to check whether the image is already downloaded. If the tag
// is "latest", or ForcePull is set, we have to check for a new version every time so we don't
// bother to check and cache the id here. We'll download first, then cache.
if driverConfig.ForcePull {
d.logger.Debug("force pulling image instead of inspecting local", "image_ref", dockerImageRef(repo, tag))
} else if tag != "latest" {
if dockerImage, _ := client.ImageInspect(d.ctx, image); dockerImage.ID != "" {
// Image exists so just increment its reference count
d.coordinator.IncrementImageReference(dockerImage.ID, image, task.ID)
var user string
if dockerImage.Config != nil {
user = dockerImage.Config.User
}
return dockerImage.ID, user, nil
}
}View on GitHub (pinned to 482b49bf1a)
Solutions
- Fix the image field in the task's driver config to a valid reference like 'nginx:1.25' or 'hashicorp/http-echo:0.2.1'.
- Check that any template/variable interpolation used to build the image name actually resolves (no empty values).
- If the image has no tag, add an explicit tag so parsing is unambiguous.
- Inspect the wrapped error (%w) in the job logs for the exact parse failure.
Example fix
// before
config {
image = ""
}
// after
config {
image = "nginx:1.25"
} Defensive patterns
Strategy: validation
Validate before calling
func validImageRef(image string) bool {
if image == "" { return false }
parts := strings.Split(image, ":")
if len(parts) > 2 { return false }
if !strings.ContainsAny(parts[0], "/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_") { return false }
return true
}
// call before submitting job: validImageRef(cfg.Image) Prevention
- Always specify image with an explicit tag
- Validate job spec with `nomad job validate` before submission
- Avoid template interpolation that can render an empty image
When it happens
Trigger: driverConfig.Image contains a reference parseDockerImage rejects — e.g. an empty image string, invalid characters, or a ref that cannot be split into repo/tag. Raised synchronously in StartTask via createImage before any pull or load happens.
Common situations: Typos in the image field of the docker task driver config, template interpolation leaving image empty (e.g. missing variable), pasting a full 'docker pull' command line, or stray whitespace/quotes in the image name.
Related errors
- 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
- failed to parse 'pull_activity_timeout' duration: %v
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/d12f6a2062d868e8.
Report an issue: GitHub.