hashicorp/nomad · error
unable to open image archive: %v
Error message
unable to open image archive: %v
What it means
loadImage opens the archive file named by driverConfig.LoadImage from the task's LocalDir; this error wraps the os.Open failure. It means the image tarball could not be read from disk before it is handed to the Docker daemon via ImageLoad.
Source
Thrown at drivers/docker/driver.go:722
// resolveRegistryAuthentication attempts to retrieve auth credentials for the
// repo, trying all authentication-backends possible.
func (d *Driver) resolveRegistryAuthentication(driverConfig *TaskConfig, repo string) (*registry.AuthConfig, error) {
return firstValidAuth(repo, []authBackend{
authFromTaskConfig(driverConfig),
authFromDockerConfig(d.config.Auth.Config),
authFromHelper(d.config.Auth.Helper),
})
}
// loadImage creates an image by loading it from the file system
func (d *Driver) loadImage(task *drivers.TaskConfig, driverConfig *TaskConfig, dockerClient *client.Client) (id string, user string, err error) {
archive := filepath.Join(task.TaskDir().LocalDir, driverConfig.LoadImage)
d.logger.Debug("loading image from disk", "archive", archive)
f, err := os.Open(archive)
if err != nil {
return "", "", fmt.Errorf("unable to open image archive: %v", err)
}
if _, err := dockerClient.ImageLoad(d.ctx, f, client.ImageLoadWithQuiet(true)); err != nil {
return "", "", err
}
f.Close()
dockerImage, err := dockerClient.ImageInspect(d.ctx, driverConfig.Image)
if err != nil {
return "", "", recoverableErrTimeouts(err)
}
d.coordinator.IncrementImageReference(dockerImage.ID, driverConfig.Image, task.ID)
var imageUser string
if dockerImage.Config != nil {
imageUser = dockerImage.Config.User
}
return dockerImage.ID, imageUser, nilView on GitHub (pinned to 482b49bf1a)
Solutions
- Add/verify an artifact stanza that downloads the image archive into the task (files land in the task's local/ dir).
- Ensure load_image is just the filename (relative to local dir), e.g. load_image = "image.tar".
- Check the Nomad client allocation directory for the file's actual presence and exact name.
- Verify task user permissions allow reading the file.
Example fix
// before
config { load_image = "app.tar" }
// after
artifact {
source = "https://example.com/app-image.tar"
}
config { load_image = "app-image.tar" } Defensive patterns
Strategy: validation
Validate before calling
archive := filepath.Join(taskDir, "local", cfg.LoadImage)
if _, err := os.Stat(archive); err != nil {
return fmt.Errorf("image archive %s not present; check artifact stanza: %w", archive, err)
} Try / catch
if _, err := os.Open(archive); err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("archive missing, ensure artifact ran: %s", archive)
}
return err
} Prevention
- Always pair load_image with an artifact stanza downloading the tar
- Use exact, case-correct filenames (Linux is case-sensitive)
- Verify file presence in allocations/local/ during dry runs
When it happens
Trigger: The task config sets load_image = "file.tar" but the file does not exist in <task_dir>/local/, the artifact that should download it failed or was not declared, or the filename/path is misspelled.
Common situations: Missing artifact stanza to fetch the tarball, artifact downloaded to a different path than local/, wrong case-sensitive filename on Linux, or referencing load_image while the file was cleaned up between allocations.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- opening seccomp profile (%s) failed: %v
- file '%s' cannot be mapped. Only directories can be mapped o
- unable to read rooted allocation directory
- plugin not found
- plugin not executable
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/6fee4d803672166f.
Report an issue: GitHub.