wagoodman/dive · error

could not find image config

Error message

could not find image config

What it means

Returned by the docker-archive loader (dive/image/docker/image_archive.go:192) when a manifest/config path was resolved (from manifest.json's Config entry or the OCI fallback) but that key is absent from the map of JSON files actually found in the tar. I.e. the metadata points at a config blob that is not present in the archive.

Source

Thrown at dive/image/docker/image_archive.go:192

			}
		}
		if len(configPath) == 0 {
			return img, fmt.Errorf("could not find image manifest")
		}

		var layerPaths []string
		for k := range img.layerMap {
			layerPaths = append(layerPaths, k)
		}
		img.manifest = manifest{
			ConfigPath:    configPath,
			LayerTarPaths: layerPaths,
		}
	}

	configContent, exists := jsonFiles[img.manifest.ConfigPath]
	if !exists {
		return img, fmt.Errorf("could not find image config")
	}

	img.config = newConfig(configContent)

	return img, nil
}

func processLayerTar(name string, reader *tar.Reader) (*filetree.FileTree, error) {
	tree := filetree.NewFileTree()
	tree.Name = name

	fileInfos, err := getFileList(reader)
	if err != nil {
		return nil, err
	}

	for _, element := range fileInfos {
		tree.FileSize += uint64(element.Size)

View on GitHub (pinned to d6c691947f)

Solutions

  1. Verify the referenced config exists: extract manifest.json (jq .[0].Config), then tar -tf app.tar | grep <that-name>
  2. Re-pull and re-save from the source of truth: docker pull app:tag && docker save -o app.tar app:tag
  3. Stop post-processing the tar (renaming, recompressing, stripping files) between save and dive
  4. If the config blob name is legitimate but renamed, repack so manifest.json's Config matches the actual filename

Example fix

# before (repacked archive with renamed blobs)
dive docker-archive://app-repacked.tar  # could not find image config

# after (pristine save)
docker pull app:tag
docker save -o app.tar app:tag
dive docker-archive://app.tar
Defensive patterns

Strategy: validation

Validate before calling

// verify every manifest-referenced config exists in the tar
func manifestConfigPresent(tarPath string) error {
    names := tarEntries(tarPath) // map[string]bool of entry names
    mf, ok := names["manifest.json"]
    if !ok {
        return nil // handled by the OCI-fallback path
    }
    _ = mf
    raw := readTarEntry(tarPath, "manifest.json")
    var m []struct{ Config string }
    if err := json.Unmarshal(raw, &m); err != nil || len(m) == 0 {
        return fmt.Errorf("unparseable manifest.json")
    }
    if !names[m[0].Config] {
        return fmt.Errorf("config %s referenced but absent", m[0].Config)
    }
    return nil
}

Try / catch

img, err := resolver.Fetch(ctx, "docker-archive://"+p)
if err != nil && strings.Contains(err.Error(), "could not find image config") {
    // archive integrity problem: regenerate from source rather than patching
    return fmt.Errorf("archive %s is incomplete (config blob missing); re-save with docker save", p)
}

Prevention

When it happens

Trigger: manifest.json referencing <digest>.json when the tar's copy of that blob was renamed or omitted; archives assembled by concatenation or by hand where the config file was dropped; OCI fallback path where isConfig matched one blob but the layerMap/manifest wiring points elsewhere; partial or restarted docker save.

Common situations: Artifacts modified/repacked between save and analysis (strip, rename, re-compress), registry-proxy caches that rewrite config blob names, and interrupted transfers.

Related errors


AI-assisted analysis of wagoodman/dive@d6c691947f (2026-08-15). Data as JSON: /api/errors/7c5253e156fbce4d. Report an issue: GitHub.