docker/compose · error

failed to scan env file %s: %w

Error message

failed to scan env file %s: %w

What it means

The pre-publish secret scanner could open/stat a service env file but the ScanFile call failed while reading it. This wraps I/O or scanner-level errors distinct from existence checks done just before.

Source

Thrown at pkg/compose/publish.go:717

			return nil, fmt.Errorf("failed to scan compose file %s: %w", file, err)
		}
		allFindings = append(allFindings, findings...)
	}
	for _, service := range project.Services {
		// Check env files
		for _, envFile := range service.EnvFiles {
			if _, statErr := os.Stat(envFile.Path); statErr != nil {
				if !os.IsNotExist(statErr) {
					return nil, fmt.Errorf("failed to access env file %s: %w", envFile.Path, statErr)
				}
				if envFile.Required {
					return nil, fmt.Errorf("env file %s not found", envFile.Path)
				}
				continue
			}
			findings, err := scan.ScanFile(envFile.Path)
			if err != nil {
				return nil, fmt.Errorf("failed to scan env file %s: %w", envFile.Path, err)
			}
			allFindings = append(allFindings, findings...)
		}
	}

	// Check configs defined by files
	for _, config := range project.Configs {
		if config.File != "" {
			findings, err := scan.ScanFile(config.File)
			if err != nil {
				return nil, fmt.Errorf("failed to scan config file %s: %w", config.File, err)
			}
			allFindings = append(allFindings, findings...)
		}
	}

	// Check secrets defined by files
	for _, secret := range project.Secrets {

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Verify the path is a regular readable file: ls -la <path> (not a directory, not a dangling symlink).
  2. Re-run the publish — transient I/O errors on network mounts often clear; if persistent, copy the file locally.
  3. Fix symlink targets or replace the env_file entry with the real path.
  4. Check dmesg/system logs for underlying disk or filesystem errors if reads keep failing.

Example fix

# before
services:
  api:
    env_file: ./secrets/   # a directory

# after
services:
  api:
    env_file: ./secrets/api.env
Defensive patterns

Strategy: retry

Validate before calling

func readableRegularFile(p string) bool {
	fi, err := os.Stat(p)
	return err == nil && fi.Mode().IsRegular()
}

Try / catch

if err := publish(ctx, opts); err != nil {
    if strings.Contains(err.Error(), "failed to scan env file") {
        // verify path is a regular file, fix symlink/target, retry once
    }
    return err
}

Prevention

When it happens

Trigger: Publishing when an env file exists and is stat-able but cannot be fully read: it is a directory, a broken symlink whose target disappears, or a read error occurs mid-file (I/O error, file truncated/replaced concurrently).

Common situations: env_file pointing at a directory; dangling symlinks; files being rotated or replaced by another process during publish; sparse remote-mounted files (NFS/FUSE) with transient read failures.

Related errors


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