influxdata/influxdb · error · ValidationError

invalid strftime format in partition template

Error message

invalid strftime format in partition template: {0}

What it means

This error is returned when a partition template defines a `TimeFormat` part whose strftime format string cannot be compiled by the underlying strftime implementation. The library validates format strings at template-construction time so invalid formatters are rejected before data is written. The offending string is carried in the `String` payload.

Solutions

  1. Fix the strftime string to use only supported directives (e.g., `%Y`, `%m`, `%d`, `%H`); test it with the same strftime implementation the library uses
  2. Verify each `%` is followed by a valid conversion specifier and there are no stray `%` characters
  3. Check the library's supported time-format directives (crate docs/chrono version) — some extensions differ across versions
  4. Validate user-supplied formats at config-ingest time with a small probe before creating the template

Example fix

// before
builder.add_strftime_format("%Y-%m-%d %Q"); // unsupported directive
// after
builder.add_strftime_format("%Y-%m-%d %H");
Defensive patterns

Strategy: validation

Validate before calling

fn probe_strftime(fmt: &str) -> bool {
    // compile the format once via the same strftime engine the library uses
    chrono::format::StrftimeItems::new(fmt).parse(fmt).is_ok()
        && !fmt.is_empty()
}
if !probe_strftime(&user_fmt) { return Err(format!("invalid strftime format: {}", user_fmt)); }

Type guard

fn valid_time_format(fmt: &str) -> Option<&str> {
    (!fmt.is_empty() && fmt.bytes().filter(|&b| b == b'%').count() > 0).then_some(fmt)
}

Try / catch

let template = builder.build().map_err(|e| match e {
    ValidationError::InvalidStrftime(fmt) => anyhow!("fix strftime format {:?}: unsupported or malformed directive", fmt),
    other => anyhow!(other),
})?;

Prevention

When it happens

Trigger: Calling `PartitionTemplateBuilder::add_strftime_format(...)` (or validating a proto template with a `TimeFormat` part) with a malformed strftime spec, e.g. an unclosed `%`, unsupported conversion specifier, or non-UTF8-incompatible pattern.

Common situations: Typos in format strings like `%Y-%m` missing a specifier or `%Q` (unsupported); copying formats from libraries with nonstandard directives; localization differences in accepted directives; empty or truncated format strings from config files.

Related errors


AI-assisted analysis of influxdata/influxdb@06200ef96b (2026-09-19). Data as JSON: /api/errors/902aff29b3d5e49c. Report an issue: GitHub.

Appendix: source

Thrown at core/data_types/src/partition_template.rs:221

    #[error("Custom partition template must have at least one part")]
    NoParts,

    /// The partition template exceeded the maximum allowed number of parts.
    #[error(
        "Custom partition template specified {specified} parts. \
        Partition templates may have a maximum of {MAXIMUM_NUMBER_OF_TEMPLATE_PARTS} parts."
    )]
    TooManyParts {
        /// The number of template parts that were present in the user-provided custom partition
        /// template.
        specified: usize,
    },

    /// The partition template defines a [`TimeFormat`] part, but the
    /// provided strftime formatter is invalid.
    ///
    /// [`TimeFormat`]: [`proto::template_part::Part::TimeFormat`]
    #[error("invalid strftime format in partition template: {0}")]
    InvalidStrftime(String),

    /// The partition template defines a [`TagValue`] part or [`Bucket`] part,
    /// but the provided tag name value is invalid.
    ///
    /// [`TagValue`]: [`proto::template_part::Part::TagValue`]
    /// [`Bucket`]: [`proto::template_part::Part::Bucket`]
    #[error("invalid tag name value in partition template: {0}")]
    InvalidTagValue(String),

    /// The partition template defines a [`Bucket`] part, but the provided
    /// number of buckets is invalid.
    ///
    /// [`Bucket`]: [`proto::template_part::Part::Bucket`]
    #[error(
        "number of buckets in partition template must be in range \
        [{ALLOWED_BUCKET_QUANTITIES:?}), number specified: {0}"
    )]

View on GitHub (pinned to 06200ef96b)