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, nil

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Add/verify an artifact stanza that downloads the image archive into the task (files land in the task's local/ dir).
  2. Ensure load_image is just the filename (relative to local dir), e.g. load_image = "image.tar".
  3. Check the Nomad client allocation directory for the file's actual presence and exact name.
  4. 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

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


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