{"record":{"id":"5e16b900192ddf4c","repo":"influxdata/influxdb","slug":"custom-partition-template-specified-specified-parts","errorCode":null,"errorMessage":"Custom partition template specified {specified} parts. Partition templates may have a maximum of {MAXIMUM_NUMBER_OF_TEMPLATE_PARTS} parts.","messagePattern":"Custom partition template specified (.+?) parts\\. Partition templates may have a maximum of (.+?) parts\\.","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"core/data_types/src/partition_template.rs","lineNumber":207,"sourceCode":"    format::{self, Numeric, StrftimeItems},\n};\nuse generated_types::influxdata::iox::partition_template::v1 as proto;\nuse murmur3::murmur3_32;\nuse percent_encoding::{AsciiSet, CONTROLS, percent_decode_str};\nuse schema::TIME_COLUMN_NAME;\nuse thiserror::Error;\n\nuse crate::{MismatchedNumPartsError, PartitionKey, PartitionKeyBuilder};\n\n/// Reasons a user-specified partition template isn't valid.\n#[derive(Debug, Error)]\npub enum ValidationError {\n    /// The partition template didn't define any parts.\n    #[error(\"Custom partition template must have at least one part\")]\n    NoParts,\n\n    /// The partition template exceeded the maximum allowed number of parts.\n    #[error(\n        \"Custom partition template specified {specified} parts. \\\n        Partition templates may have a maximum of {MAXIMUM_NUMBER_OF_TEMPLATE_PARTS} parts.\"\n    )]\n    TooManyParts {\n        /// The number of template parts that were present in the user-provided custom partition\n        /// template.\n        specified: usize,\n    },\n\n    /// The partition template defines a [`TimeFormat`] part, but the\n    /// provided strftime formatter is invalid.\n    ///\n    /// [`TimeFormat`]: [`proto::template_part::Part::TimeFormat`]\n    #[error(\"invalid strftime format in partition template: {0}\")]\n    InvalidStrftime(String),\n\n    /// The partition template defines a [`TagValue`] part or [`Bucket`] part,\n    /// but the provided tag name value is invalid.","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/core/data_types/src/partition_template.rs#L189-L225","documentation":"This error is returned when a custom partition template specifies more parts than the allowed maximum, `MAXIMUM_NUMBER_OF_TEMPLATE_PARTS`. Partition templates with too many parts create excessive small partitions and degrade performance, so the library enforces an upper bound during validation. The error reports how many parts were specified versus the maximum allowed.","triggerScenarios":"Calling `PartitionTemplateBuilder::build()` (or validating a proto template) after adding more parts than `MAXIMUM_NUMBER_OF_TEMPLATE_PARTS`, e.g. many chained `add_tag_part`/`add_strftime_format`/`add_bucket_part` calls, or constructing from a user-supplied parts list exceeding the limit.","commonSituations":"Users modelling very high-cardinality hierarchies (e.g., tag per dimension) in DDL requests; config-driven template generation that expands every column into a part; porting templates from systems without a part-count limit.","solutions":["Reduce the number of template parts to `MAXIMUM_NUMBER_OF_TEMPLATE_PARTS` or fewer, keeping only the highest-value dimensions","Collapse several low-cardinality tag parts into a single bucket part or combine tags before partitioning","Check the constant value in the current library version and validate user input against it before submitting","For deeply nested time granularity, use fewer strftime parts (e.g., one `%Y-%m-%d` instead of separate year/month/day)"],"exampleFix":"// before\nlet template = PartitionTemplateBuilder::new()\n    .add_tag_part(\"a\").add_tag_part(\"b\").add_tag_part(\"c\")\n    .add_tag_part(\"d\").add_tag_part(\"e\")\n    .build()?; // TooManyParts if > MAXIMUM_NUMBER_OF_TEMPLATE_PARTS\n// after\nlet template = PartitionTemplateBuilder::new()\n    .add_tag_part(\"a\").add_tag_part(\"b\") // stay within the max\n    .build()?;","handlingStrategy":"validation","validationCode":"use crate::partition_template::MAXIMUM_NUMBER_OF_TEMPLATE_PARTS;\nfn check_part_count(parts: &[TemplatePart]) -> Result<(), String> {\n    if parts.len() > MAXIMUM_NUMBER_OF_TEMPLATE_PARTS {\n        return Err(format!(\"{} parts exceeds max {}\", parts.len(), MAXIMUM_NUMBER_OF_TEMPLATE_PARTS));\n    }\n    Ok(())\n}","typeGuard":"fn within_part_limit(parts: &[TemplatePart]) -> bool {\n    parts.len() <= MAXIMUM_NUMBER_OF_TEMPLATE_PARTS\n}","tryCatchPattern":"let template = builder.build().map_err(|e| match e {\n    ValidationError::TooManyParts { specified } => {\n        anyhow!(\"trim template to <= {} parts (got {})\", MAXIMUM_NUMBER_OF_TEMPLATE_PARTS, specified)\n    }\n    other => anyhow!(other),\n})?;","preventionTips":["Limit partitioning to the few highest-cardinality, most-queried dimensions","Collapse many small tag parts into one bucket part to stay under the limit","Validate user-supplied template part counts at config-ingest time against MAXIMUM_NUMBER_OF_TEMPLATE_PARTS","Merge adjacent strftime granularities (year/month/day) into a single format string"],"tags":["rust","partition-template","validation","limit-exceeded"],"backgroundTag":"value-out-of-range","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}