{"record":{"id":"92b971bd24bc71ef","repo":"docker/compose","slug":"failed-to-scan-secret-file-s-w","errorCode":null,"errorMessage":"failed to scan secret file %s: %w","messagePattern":"failed to scan secret file (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/compose/publish.go","lineNumber":739,"sourceCode":"\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 {\n\t\tif secret.File != \"\" {\n\t\t\tfindings, err := scan.ScanFile(secret.File)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to scan secret file %s: %w\", secret.File, err)\n\t\t\t}\n\t\t\tallFindings = append(allFindings, findings...)\n\t\t}\n\t}\n\n\treturn allFindings, nil\n}\n\nfunc composeFileAsByteReader(ctx context.Context, filePath string, project *types.Project) (io.Reader, error) {\n\tbase, err := loadUnresolvedFile(ctx, project, filePath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to load compose file %s: %w\", filePath, err)\n\t}\n\tin, err := base.MarshalYAML()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn bytes.NewBuffer(in), nil","sourceCodeStart":721,"sourceCodeEnd":757,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/pkg/compose/publish.go#L721-L757","documentation":"The pre-publish secret scan failed reading a top-level secret defined by file (secrets.<name>.file). Compose attempts to scan secret file contents like env and config files; a read failure aborts the publish.","triggerScenarios":"Publishing a project with a secrets: section whose file path cannot be read: missing-but-symlinked, directory instead of file, permission denied at read time, or I/O error.","commonSituations":"Secret files injected only at runtime (not present when publishing); paths pointing outside the repository; files owned by root in CI; rotated credentials files replaced mid-scan.","solutions":["Ensure the secret file exists at the referenced path and is readable by the user running compose publish.","Add a CI step that materializes secret files (from the CI secret store) before publishing.","Correct the path or use environment-based secrets (environment: key) instead of file-based ones when the file is not available at publish time.","If secrets are external (driver-based), remove the file: reference so no local scan is required."],"exampleFix":"# before\nsecrets:\n  db-password:\n    file: /run/secrets/db_password   # absent at publish time\n\n# after\nsecrets:\n  db-password:\n    environment: DB_PASSWORD         # resolved from project environment","handlingStrategy":"validation","validationCode":"func secretFilesReadable(project *types.Project) error {\n\tfor name, sec := range project.Secrets {\n\t\tif sec.File == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif fi, err := os.Stat(sec.File); err != nil || !fi.Mode().IsRegular() {\n\t\t\treturn fmt.Errorf(\"secret %s file %q unreadable\", name, sec.File)\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":null,"tryCatchPattern":"if err := publish(ctx, opts); err != nil {\n    if strings.Contains(err.Error(), \"failed to scan secret file\") {\n        // inject the secret file from the secret store, then retry\n    }\n    return err\n}","preventionTips":["Inject secret files from the CI secret manager before compose runs.","Prefer environment: or external driver-backed secrets when files are absent at publish time.","Verify secret file paths and permissions in a pre-flight check."],"tags":["compose","publish","secrets","secret-scanning","io"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}