fluent/fluentd · error · Fluent::ConfigError
out_secondary_file: basename or directory has an incompatibl
Error message
out_secondary_file: basename or directory has an incompatible placeholder, remove time formats, like `%Y%m%d`, from basename or directory
What it means
SecondaryFileOutput#configure validates its output path against the PRIMARY buffer's chunk keys. If the primary <buffer> has no `time` chunk key (@chunk_key_time false) but the directory/basename string contains strftime directives (detected by has_time_format?: the string changes when run through Time.now.strftime), this Fluent::ConfigError fires. The secondary writes chunks the primary already queued, and without a time chunk key there is no time value to expand %Y%m%d-style placeholders with.
Source
Thrown at lib/fluent/plugin/out_secondary_file.rb:98
}
when :gzip
File.open(path, "ab", @file_perm) {|f|
f.flock(File::LOCK_EX)
gz = Zlib::GzipWriter.new(f)
chunk.write_to(gz)
gz.close
}
end
end
end
private
def validate_compatible_with_primary_buffer!(path_without_suffix)
placeholders = path_without_suffix.scan(PLACEHOLDER_REGEX).flat_map(&:first) # to trim suffix [\d+]
if !@chunk_key_time && has_time_format?(path_without_suffix)
raise Fluent::ConfigError, "out_secondary_file: basename or directory has an incompatible placeholder, remove time formats, like `%Y%m%d`, from basename or directory"
end
if !@chunk_key_tag && (ph = placeholders.find { |placeholder| placeholder.match?(/tag(\[\d+\])?/) })
raise Fluent::ConfigError, "out_secondary_file: basename or directory has an incompatible placeholder #{ph}, remove tag placeholder, like `${tag}`, from basename or directory"
end
vars = placeholders.reject { |placeholder| placeholder.match?(/tag(\[\d+\])?/) || (placeholder == 'chunk_id') }
if ph = vars.find { |v| !@chunk_keys.include?(v) }
raise Fluent::ConfigError, "out_secondary_file: basename or directory has an incompatible placeholder #{ph}, remove variable placeholder, like `${varname}`, from basename or directory"
end
end
def has_time_format?(str)
str != Time.now.strftime(str)
end
def generate_path(path_without_suffix)View on GitHub (pinned to dd45c6e18d)
Solutions
- Add the time key to the primary buffer: `<buffer time>` (usually `<buffer time, tag>`) with an appropriate `timekey`, so chunks carry the time needed to expand the format
- Or remove the time formats from directory/basename and use a flat path
- Confirm with `fluentd --dry-run` — this is caught at configure time
Example fix
# before
<match **>
@type forward
<buffer tag> # no time chunk key
...
</buffer>
<secondary>
@type secondary_file
directory /var/log/dump/%Y%m%d
</secondary>
</match>
# after
<match **>
@type forward
<buffer time, tag>
timekey 1d
</buffer>
<secondary>
@type secondary_file
directory /var/log/dump/%Y%m%d
</secondary>
</match> Defensive patterns
Strategy: validation
Validate before calling
# Check: time formats in the secondary path require a time chunk key in the primary buffer
buffer = match_element.elements.find { |e| e.name == 'buffer' }
keys = buffer && buffer.arg.to_s.split(',').map(&:strip)
has_time_key = keys && keys.include?('time')
path = File.join(directory, basename || 'dump.bin')
raise 'time format in path but primary buffer has no time key' if !has_time_key && path != Time.now.strftime(path) Prevention
- Keep a mental checklist: %Y/%m/%d in secondary path ⇒ primary must declare `<buffer ... time>` with a timekey
- Beware stray %-escapes in basenames from templating — has_time_format? triggers on any strftime directive
- Dry-run secondary_file configs after ANY change to the primary buffer's chunk keys
When it happens
Trigger: `<buffer>` or `<buffer tag>` (no `time` key) combined with a secondary_file path containing time formats, e.g. `directory /var/log/dump/%Y%m%d` or `basename dump.%Y%m%d.bin`. Any literal %Y/%m/%d/%H anywhere in the path triggers it, not just ${time} placeholders.
Common situations: Copying date-partitioned paths from out_file configs; adding time-based directory layout to the secondary without switching the primary to `<buffer time>`; a basename that happens to contain a %-escape from a templating system.
Related errors
- out_secondary_file: basename or directory has an incompatibl
- out_secondary_file: basename or directory has an incompatibl
- This plugin can only be used in the <secondary> section
- buffer path is not configured. specify 'path' in <buffer>
- basename should not include `/`
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/dc6652e615392b22.
Report an issue: GitHub.