{"record":{"id":"a74364d835b25708","repo":"fluent/fluentd","slug":"directory-is-not-writable-for-plugin-storage-file","errorCode":null,"errorMessage":"Directory is not writable for plugin storage file '#{@path}'","messagePattern":"Directory is not writable for plugin storage file '#(.+?)'","errorType":"exception","errorClass":"Fluent::ConfigError","httpStatus":null,"severity":"error","filePath":"lib/fluent/plugin/storage_local.rb","lineNumber":100,"sourceCode":"        if !@on_memory\n          dir = File.dirname(@path)\n          FileUtils.mkdir_p(dir, mode: @dir_mode) unless Dir.exist?(dir)\n          if File.exist?(@path)\n            raise Fluent::ConfigError, \"Plugin storage path '#{@path}' is not readable/writable\" unless File.readable?(@path) && File.writable?(@path)\n            begin\n              data = File.open(@path, 'r:utf-8:utf-8') { |io| io.read }\n              if data.empty?\n                log.warn \"detect empty plugin storage file during startup. Ignored: #{@path}\"\n                return\n              end\n              data = JSON.parse(data, Fluent::DEFAULT_JSON_PARSE_OPTIONS)\n              raise Fluent::ConfigError, \"Invalid contents (not object) in plugin storage file: '#{@path}'\" unless data.is_a?(Hash)\n            rescue => e\n              log.error \"failed to read data from plugin storage file\", path: @path, error: e\n              raise Fluent::ConfigError, \"Unexpected error: failed to read data from plugin storage file: '#{@path}'\"\n            end\n          else\n            raise Fluent::ConfigError, \"Directory is not writable for plugin storage file '#{@path}'\" unless File.stat(dir).writable?\n          end\n        end\n      end\n\n      def multi_workers_ready?\n        unless @multi_workers_available\n          log.error \"local plugin storage with multi workers should be configured to use directory 'path', or system root_dir and plugin id\"\n        end\n        @multi_workers_available\n      end\n\n      def load\n        return if @on_memory\n        return unless File.exist?(@path)\n        begin\n          json_string = File.open(@path, 'r:utf-8:utf-8'){ |io| io.read }\n          json = JSON.parse(json_string, Fluent::DEFAULT_JSON_PARSE_OPTIONS)\n          unless json.is_a?(Hash)","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/fluent/fluentd/blob/dd45c6e18dc7be33b5e5a0f0767bf46307ff5626/lib/fluent/plugin/storage_local.rb#L82-L118","documentation":"When the storage file does not yet exist, LocalStorage#configure creates its parent directory with FileUtils.mkdir_p and then requires that directory to be writable (File.stat(dir).writable?, storage_local.rb:100); if it is not, this Fluent::ConfigError aborts configuration. Fluentd needs to create the file on first save, so an unwritable parent directory makes persistence impossible and the misconfiguration is reported at startup rather than at first save.","triggerScenarios":"path (or the root_dir/@id-derived directory) points into a directory owned by root or another user while fluentd runs unprivileged; directory mode 0555 or on a read-only filesystem; SELinux denial on the state directory; typo'd path resolving to a protected location like /etc or /.","commonSituations":"First run of a persistent-storage plugin after adding @id without pre-creating the state directory; switching the service to a non-root user without chown-ing the parent dir; read-only root filesystems in containers where the state dir was not mounted writable.","solutions":["Make the parent directory writable by the fluentd user: chown fluent:fluent /var/log/fluent && chmod 0755 /var/log/fluent","Point path at a location the runtime user can write, such as /var/log/fluent/ or a dedicated state directory","In containers, ensure the state path is a writable volume mount (and not on the read-only image layer)","Check for SELinux/AppArmor denials if classic permissions look correct (audit.log or ausearch -m avc)"],"exampleFix":"# before\n$ ls -ld /var/lib/fluent\n drwxr-xr-x 2 root root 4096 /var/lib/fluent\n# fluentd runs as 'fluent' => Directory is not writable for plugin storage file\n\n# after\n$ sudo chown -R fluent:fluent /var/lib/fluent\n$ sudo chmod 0755 /var/lib/fluent","handlingStrategy":"validation","validationCode":"dir = File.dirname('/var/log/fluent/storage.json')\nFileUtils.mkdir_p(dir) unless Dir.exist?(dir)\nraise \"directory #{dir} not writable\" unless File.stat(dir).writable?","typeGuard":null,"tryCatchPattern":"begin\n  plugin.configure(conf)\nrescue Fluent::ConfigError => e\n  if e.message.include?('Directory is not writable for plugin storage file')\n    warn 'chown/chmod the storage directory or move path to a writable volume'; exit 1\n  end\n  raise\nend","preventionTips":["Pre-create state directories with correct ownership in provisioning (not relying on fluentd's mkdir_p under the wrong user)","In containers, mount state paths as writable volumes; the image layer is read-only","Check SELinux/AppArmor contexts when classic permissions look fine but stat-writable dirs still fail"],"tags":["fluentd","storage","permissions","filesystem","config-error","startup"],"backgroundTag":"directory-permission-denied","analyzedSha":"dd45c6e18dc7be33b5e5a0f0767bf46307ff5626","analyzedAt":"2026-08-21T16:22:07.332Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}