{"record":{"id":"4d270a68bd23c8cf","repo":"lima-vm/lima","slug":"failed-to-read-boot-scripts-directory-q-w","errorCode":null,"errorMessage":"failed to read boot scripts directory %#q: %w","messagePattern":"failed to read boot scripts directory %#q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/guestagent/fakecloudinit/fakecloudinit_darwin.go","lineNumber":386,"sourceCode":"\t// FIXME: avoid hardcoding the primary network name\n\tconst primaryNetwork = \"Ethernet\"\n\tcmd := exec.CommandContext(ctx, \"networksetup\", append([]string{\"-setdnsservers\", primaryNetwork}, resolvConf.Nameservers...)...)\n\tlogrus.Infof(\"Executing command: %v\", cmd.Args)\n\tif output, err := cmd.CombinedOutput(); err != nil {\n\t\treturn fmt.Errorf(\"failed to execute command %v: %w (output=%#q)\", cmd.Args, err, output)\n\t}\n\treturn nil\n}\n\nfunc runBootScripts(ctx context.Context) error {\n\tdirs := []string{\n\t\t\"/var/lib/cloud/scripts/per-boot\",\n\t}\n\tvar errs []error\n\tfor _, dir := range dirs {\n\t\tdirEntries, err := os.ReadDir(dir)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to read boot scripts directory %#q: %w\", dir, err)\n\t\t}\n\t\tfor _, entry := range dirEntries {\n\t\t\tif entry.IsDir() {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tscriptPath := filepath.Join(dir, entry.Name())\n\t\t\t// entry.Type().Mode() does not seem to contain permission bits\n\t\t\tentryInfo, err := entry.Info()\n\t\t\tif err != nil {\n\t\t\t\tlogrus.Warnf(\"Skipping boot script %#q due to stat error: %v\", scriptPath, err)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif entryInfo.Mode().Perm()&0o111 == 0 {\n\t\t\t\tlogrus.Warnf(\"Skipping non-executable boot script %#q (%v)\", scriptPath, entryInfo.Mode().Perm())\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tcmd := exec.CommandContext(ctx, scriptPath)\n\t\t\tcmd.Stdout = os.Stdout","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/guestagent/fakecloudinit/fakecloudinit_darwin.go#L368-L404","documentation":"runBootScripts enumerates per-once and per-boot script directories (cloud-init style, e.g. /var/lib/cloud/scripts/per-boot) with os.ReadDir. If a directory cannot be read, provisioning fails with this wrapped error instead of continuing. This typically means the directory is missing or unreadable.","triggerScenarios":"One of the boot-script directories (per-once or /var/lib/cloud/scripts/per-boot) does not exist on the macOS guest, is a file instead of a directory, or the process lacks read permission for it.","commonSituations":"Fresh macOS guest where the cloud-init directory layout was never created; a previous provisioning step deleted the directory; mounting a volume over /var/lib/cloud that hides the scripts dir.","solutions":["Create the missing directory in the guest (e.g. `sudo mkdir -p /var/lib/cloud/scripts/per-boot`).","Make provisioning create the directories (os.MkdirAll) before runBootScripts reads them, or treat ENOENT as empty.","Check the wrapped error: ENOENT means missing dir; EACCES means permission problem - fix ownership accordingly.","Ensure no earlier user-data step removes or replaces /var/lib/cloud."],"exampleFix":"// before\ndirEntries, err := os.ReadDir(dir)\n// after\nif err := os.MkdirAll(dir, 0o755); err != nil { ... }\ndirEntries, err := os.ReadDir(dir)","handlingStrategy":"fallback","validationCode":"for _, dir := range []string{\"/var/lib/cloud/scripts/per-once\", \"/var/lib/cloud/scripts/per-boot\"} {\n    if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {\n        os.MkdirAll(dir, 0o755)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := runBootScripts(ctx); err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && errors.Is(pe.Err, syscall.ENOENT) {\n        // directory missing: create it or treat as no scripts\n    }\n}","preventionTips":["Provision the cloud-init script directories before enabling boot scripts.","Do not mount volumes over /var/lib/cloud.","Treat a missing per-boot directory as an empty script set rather than a fatal error."],"tags":["cloud-init","macos","boot-scripts","filesystem"],"backgroundTag":"directory-not-found","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}