docker/compose · error

inspecting %q: %w

Error message

inspecting %q: %w

What it means

ArchiveBuilder.ArchivePathsIfExist walks each HostPath via entriesForPath to collect tar entries. Walking errors that are NOT 'file does not exist' (which is silently skipped there) bubble up wrapped as 'inspecting %q'. It means compose could not read the local tree for the named path.

Source

Thrown at internal/sync/tar.go:157

}

// ArchivePathsIfExist creates a tar archive of all local files in `paths`. It quietly skips any paths that don't exist.
func (a *ArchiveBuilder) ArchivePathsIfExist(paths []PathMapping) error {
	// In order to handle overlapping syncs, we
	// 1) collect all the entries,
	// 2) de-dupe them, with last-one-wins semantics
	// 3) write all the entries
	//
	// It's not obvious that this is the correct behavior. A better approach
	// (that's more in-line with how syncs work) might ignore files in earlier
	// path mappings when we know they're going to be "synced" over.
	// There's a bunch of subtle product decisions about how overlapping path
	// mappings work that we're not sure about.
	var entries []archiveEntry
	for _, p := range paths {
		newEntries, err := a.entriesForPath(p.HostPath, p.ContainerPath)
		if err != nil {
			return fmt.Errorf("inspecting %q: %w", p.HostPath, err)
		}

		entries = append(entries, newEntries...)
	}

	entries = dedupeEntries(entries)
	for _, entry := range entries {
		err := a.writeEntry(entry)
		if err != nil {
			return fmt.Errorf("archiving %q: %w", entry.path, err)
		}
	}
	return nil
}

func (a *ArchiveBuilder) writeEntry(entry archiveEntry) error {
	pathInTar := entry.path
	header := entry.header

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Fix read/traverse permissions on the named host path and its parents for the user running compose
  2. Re-check broken symlinks under the synced root: find <path> -xtype l; repair or exclude them
  3. Exclude unreadable subtrees from the sync mapping (paths are explicit in PathMapping)
  4. If it is a network mount, remount and retry once it is healthy

Example fix

# reproduce the walk failure as the same user
find '/path/from/error' -newer /dev/null 2>&1 | head
# permission denied -> grant read+execute:
chmod -R u+rX /path/from/error
Defensive patterns

Strategy: validation

Validate before calling

// dry-run readability of the sync root before Sync
if err := checkReadableTree(hostRoot); err != nil { // filepath.Walk with os.Open on each dir
    return err
}

Try / catch

// match on the 'inspecting %q' wrapped PathError to pinpoint the unreadable subtree, grant perms, retry Sync

Prevention

When it happens

Trigger: os.Stat(localPath) on the mapping root returning a non-NotExist error, or os.Readlink failing on a symlink found during the walk (e.g. permission denied on the link target lookup).

Common situations: Bind-sync roots with mixed ownership (root-owned dirs under a user-run compose), symlinks on restricted paths, or filesystems returning EACCES/EIO during recursive enumeration.

Related errors


AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15). Data as JSON: /api/errors/3cce740ddb5e4867. Report an issue: GitHub.