{"record":{"id":"f0e3e4d15ca1ad28","repo":"docker/compose","slug":"failed-to-scan-env-file-s-w","errorCode":null,"errorMessage":"failed to scan env file %s: %w","messagePattern":"failed to scan env file (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/compose/publish.go","lineNumber":717,"sourceCode":"\t\t\treturn nil, fmt.Errorf(\"failed to scan compose file %s: %w\", file, err)\n\t\t}\n\t\tallFindings = append(allFindings, findings...)\n\t}\n\tfor _, service := range project.Services {\n\t\t// Check env files\n\t\tfor _, envFile := range service.EnvFiles {\n\t\t\tif _, statErr := os.Stat(envFile.Path); statErr != nil {\n\t\t\t\tif !os.IsNotExist(statErr) {\n\t\t\t\t\treturn nil, fmt.Errorf(\"failed to access env file %s: %w\", envFile.Path, statErr)\n\t\t\t\t}\n\t\t\t\tif envFile.Required {\n\t\t\t\t\treturn nil, fmt.Errorf(\"env file %s not found\", envFile.Path)\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tfindings, err := scan.ScanFile(envFile.Path)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to scan env file %s: %w\", envFile.Path, err)\n\t\t\t}\n\t\t\tallFindings = append(allFindings, findings...)\n\t\t}\n\t}\n\n\t// Check configs defined by files\n\tfor _, config := range project.Configs {\n\t\tif config.File != \"\" {\n\t\t\tfindings, err := scan.ScanFile(config.File)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to scan config file %s: %w\", config.File, err)\n\t\t\t}\n\t\t\tallFindings = append(allFindings, findings...)\n\t\t}\n\t}\n\n\t// Check secrets defined by files\n\tfor _, secret := range project.Secrets {","sourceCodeStart":699,"sourceCodeEnd":735,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/pkg/compose/publish.go#L699-L735","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Verify the path is a regular readable file: ls -la <path> (not a directory, not a dangling symlink).","Re-run the publish — transient I/O errors on network mounts often clear; if persistent, copy the file locally.","Fix symlink targets or replace the env_file entry with the real path.","Check dmesg/system logs for underlying disk or filesystem errors if reads keep failing."],"exampleFix":"# before\nservices:\n  api:\n    env_file: ./secrets/   # a directory\n\n# after\nservices:\n  api:\n    env_file: ./secrets/api.env","handlingStrategy":"retry","validationCode":"func readableRegularFile(p string) bool {\n\tfi, err := os.Stat(p)\n\treturn err == nil && fi.Mode().IsRegular()\n}","typeGuard":null,"tryCatchPattern":"if err := publish(ctx, opts); err != nil {\n    if strings.Contains(err.Error(), \"failed to scan env file\") {\n        // verify path is a regular file, fix symlink/target, retry once\n    }\n    return err\n}","preventionTips":["Point env_file at regular files, never directories or generated-on-the-fly paths.","Avoid rotating/replacing env files concurrently with publish.","On network filesystems, copy env files locally before publishing."],"tags":["compose","publish","env-file","secret-scanning","io"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}