{"record":{"id":"aa285699551de858","repo":"thanos-io/thanos","slug":"create-s","errorCode":null,"errorMessage":"create %s","messagePattern":"create (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/rules/manager.go","lineNumber":339,"sourceCode":"// special field in configGroups.configRuleAdapter struct.\nfunc (m *Manager) Update(evalInterval time.Duration, files []string) error {\n\tvar (\n\t\terrs            errutil.MultiError\n\t\tfilesByStrategy = map[storepb.PartialResponseStrategy][]string{}\n\t\truleFiles       = map[string]string{}\n\t)\n\n\t// Initialize filesByStrategy for existing managers' strategies to make\n\t// sure that managers are updated when they have no rules configured.\n\tfor strategy := range m.mgrs {\n\t\tfilesByStrategy[strategy] = make([]string, 0)\n\t}\n\n\tif err := os.RemoveAll(m.workDir); err != nil {\n\t\treturn errors.Wrapf(err, \"remove %s\", m.workDir)\n\t}\n\tif err := os.MkdirAll(m.workDir, os.ModePerm); err != nil {\n\t\treturn errors.Wrapf(err, \"create %s\", m.workDir)\n\t}\n\n\tfor _, fn := range files {\n\t\tb, err := os.ReadFile(filepath.Clean(fn))\n\t\tif err != nil {\n\t\t\terrs.Add(err)\n\t\t\tcontinue\n\t\t}\n\n\t\tvar rg configGroups\n\t\tif err := yaml.Unmarshal(b, &rg); err != nil {\n\t\t\terrs.Add(errors.Wrap(err, fn))\n\t\t\tcontinue\n\t\t}\n\n\t\t// NOTE: This is very ugly, but we need to write those yaml into tmp dir without the partial partial response field\n\t\t// which is not supported, to be able to reuse rules.Manager. The problem is that it uses yaml.UnmarshalStrict.\n\t\tgroupsByStrategy := map[storepb.PartialResponseStrategy][]configRuleAdapter{}","sourceCodeStart":321,"sourceCodeEnd":357,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/rules/manager.go#L321-L357","documentation":"After removing workDir, Update recreates it with os.MkdirAll(m.workDir, os.ModePerm). Failure here (typically permission denied or a read-only parent) is wrapped as \"create %s\" and blocks loading the new rule files.","triggerScenarios":"os.MkdirAll fails because the parent directory does not exist and cannot be created, permissions deny creation, the path exists as a file, or the filesystem is read-only (e.g. read-only rootfs).","commonSituations":"Container running with read-only root filesystem and workDir on it; default workDir path not writable by the runtime user; path collision where workDir is an existing regular file; missing parent after volume remount.","solutions":["Point the rules dir at a writable location (emptyDir volume in K8s, or /var/lib/thanos/rules with correct ownership)","Verify the parent of workDir exists and is writable by the process user","Ensure workDir is not an existing regular file (rm or rename it)","Add the path to the read-only-rootfs container's writable volumes"],"exampleFix":"// before\nworkDir: /rules   # read-only rootfs, path missing\n// after (K8s)\nvolumes:\n  - name: rules-dir\n    emptyDir: {}\n# container arg: --rules-dir=/var/lib/thanos/rules","handlingStrategy":"validation","validationCode":"if info, err := os.Stat(workDir); err == nil && !info.IsDir() {\n    return fmt.Errorf(\"workDir %s exists and is not a directory\", workDir)\n}\nif err := os.MkdirAll(filepath.Dir(workDir), 0o755); err != nil {\n    return fmt.Errorf(\"parent of workDir not creatable: %w\", err)\n}","typeGuard":"func ensureDirWritable(p string) error {\n    if info, err := os.Stat(p); err == nil && !info.IsDir() {\n        return fmt.Errorf(\"%s is not a directory\", p)\n    }\n    return os.MkdirAll(p, 0o755)\n}","tryCatchPattern":"if err := os.MkdirAll(m.workDir, os.ModePerm); err != nil {\n    if errors.Is(err, fs.ErrPermission) {\n        // fallback: use a temp dir\n        tmp, terr := os.MkdirTemp(\"\", \"thanos-rules\")\n        if terr == nil { m.workDir = tmp }\n    }\n    return errors.Wrapf(err, \"create %s\", m.workDir)\n}","preventionTips":["Use an emptyDir/writable volume for the rules dir in containers","Verify the default workDir path is writable by the runtime user at startup","Check read-only rootfs settings before deploy"],"tags":["filesystem","permissions","mkdir"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}