GoogleContainerTools/skaffold · error
reading image %q: %w
Error message
reading image %q: %w
What it means
Push loads the local image tarball with tarball.ImageFromPath and returns "reading image %q" when the file cannot be read or parsed as a Docker/OCI image archive. The wrapped error distinguishes filesystem problems (missing file, permissions) from format problems (invalid tar, no manifest.json).
Source
Thrown at pkg/skaffold/docker/remote.go:110
func RetrieveRemoteConfig(identifier string, cfg Config, platform v1.Platform) (*v1.ConfigFile, error) {
img, err := getRemoteImage(identifier, cfg, platform)
if err != nil {
return nil, err
}
return img.ConfigFile()
}
// Push pushes the tarball image
func Push(tarPath, tag string, cfg Config, platforms []specs.Platform) (string, error) {
t, err := name.NewTag(tag, name.WeakValidation)
if err != nil {
return "", fmt.Errorf("parsing tag %q: %w", tag, err)
}
i, err := tarball.ImageFromPath(tarPath, nil)
if err != nil {
return "", fmt.Errorf("reading image %q: %w", tarPath, err)
}
if err := remote.Write(t, i, remote.WithAuthFromKeychain(primaryKeychain)); err != nil {
return "", fmt.Errorf("%s %q: %w", sErrors.PushImageErr, t, err)
}
return getRemoteDigest(tag, cfg, platforms)
}
func getRemoteImage(identifier string, cfg Config, platform v1.Platform) (v1.Image, error) {
ref, err := parseReference(identifier, cfg)
if err != nil {
return nil, err
}
options := []remote.Option{
remote.WithAuthFromKeychain(primaryKeychain),
}
if IsInsecure(ref, cfg.GetInsecureRegistries()) {View on GitHub (pinned to a1189de023)
Solutions
- Verify the tarball exists and is non-empty: `ls -la <tarPath>`; if missing, fix the build step that produces it.
- Check it's a docker-save archive: `tar -tf img.tar | grep manifest.json` — if absent, regenerate with `docker save -o img.tar <image>`.
- If the source is an OCI layout, convert it first (e.g. `skopeo copy oci:dir docker-archive:img.tar`).
- Confirm the file path passed is the file itself, not the containing directory.
- Re-run the image build/save to rule out a truncated or corrupted archive.
Example fix
// before
os.IsDir check missing; digest, err := docker.Push("out/image", tag, cfg, nil)
// after
if fi, err := os.Stat("out/image.tar"); err != nil || fi.IsDir() { return fmt.Errorf("image tarball missing: out/image.tar") }
digest, err := docker.Push("out/image.tar", tag, cfg, nil) Defensive patterns
Strategy: validation
Validate before calling
func validateImageTar(path string) error {
fi, err := os.Stat(path)
if err != nil { return fmt.Errorf("tarball missing: %w", err) }
if fi.IsDir() || fi.Size() == 0 { return fmt.Errorf("%s is not a non-empty file", path) }
f, err := os.Open(path)
if err != nil { return err }
defer f.Close()
tr := tar.NewReader(f)
for {
h, err := tr.Next()
if err == io.EOF { return errors.New("no manifest.json in archive") }
if err != nil { return err }
if h.Name == "manifest.json" { return nil }
}
} Type guard
func isDockerSaveTar(path string) bool { return validateImageTar(path) == nil } Try / catch
if err := validateImageTar(tarPath); err != nil { return err }
if _, err := docker.Push(tarPath, tag, cfg, platforms); err != nil {
if strings.Contains(err.Error(), "reading image") {
return fmt.Errorf("%s is not a valid docker-save archive; regenerate with `docker save -o %s <image>`", tarPath, tarPath)
}
return err
} Prevention
- Always produce the tarball with `docker save -o` before pushing.
- Stat the file (exists, regular, non-empty) before calling Push.
- Convert OCI layouts with skopeo before use — tarball.ImageFromPath expects docker-save format.
- Fail the pipeline early if the producing build step reports any error.
When it happens
Trigger: tarPath points to a nonexistent file or wrong path; the file is not a `docker save` archive (e.g. it's a single-layer tar, an OCI layout dir, or compressed); the archive's manifest.json is missing or corrupted.
Common situations: Build step silently failed so the .tar was never produced; passing a directory instead of a tar; passing a docker buildx output in OCI layout format where tarball.ImageFromPath expects docker-save format; partial download/truncated file.
Related errors
- INIT_DOCKER_NETWORK_INVALID_MODE
- INIT_DOCKER_NETWORK_INVALID_CONTAINER_NAME
- walking %q: %w
- cannot call Run with empty container config
- parsing tag %q: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/0a6fb13900a3cd74.
Report an issue: GitHub.