influxdata/influxdb · error · Error

invalid gen1 duration

Error message

invalid gen1 duration {0}. Must be one of 1m, 5m, 10m

What it means

Error::InvalidGen1Duration is thrown when a gen1 duration value is supplied that is not one of the three allowed values: 1 minute, 5 minutes, or 10 minutes. The gen1 duration determines the granularity of the parquet file generations the WAL produces, and the library intentionally restricts it to a fixed allowlist. The offending value is included in the message so you can see what was rejected.

Solutions

  1. Change the configured value to exactly one of the allowed strings: '1m', '5m', or '10m'.
  2. If the value comes from a Duration, snap it to 60, 300, or 600 seconds before calling try_from.
  3. Validate the duration at config load time and fail fast with the allowlist in the message.
  4. If you need other values, this is not configurable in this version — pick the closest allowed value or upgrade the library.

Example fix

// before
let d: Gen1Duration = "30s".parse()?; // InvalidGen1Duration("30s")
// after
let d: Gen1Duration = "1m".parse()?; // ok: 1m | 5m | 10m only
Defensive patterns

Strategy: validation

Validate before calling

const ALLOWED: [&str; 3] = ["1m", "5m", "10m"];
fn validate_gen1(s: &str) -> Result<(), String> {
    if ALLOWED.contains(&s) { Ok(()) } else { Err(format!("invalid gen1 duration {s}: must be one of 1m, 5m, 10m")) }
}

Type guard

fn is_valid_gen1(s: &str) -> bool { matches!(s, "1m" | "5m" | "10m") }

Prevention

When it happens

Trigger: Parsing a duration string with Gen1Duration::from_str that is not '1m', '5m', or '10m' (lib.rs:234), or calling Gen1Duration::try_from(Duration) with a Duration that is not 60s, 300s, or 600s (lib.rs:245).

Common situations: A config file or CLI flag like --gen1-duration set to '30s', '1h', or '2m'; an environment variable with a typo; passing a programmatically computed Duration that lands on an unsupported value.

Understand the failure class

Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.

Related errors


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

Appendix: source

Thrown at influxdb3_wal/src/lib.rs:55

    #[error("wal buffer full with {0} ops")]
    BufferFull(usize),

    #[error("error writing wal file: {0}")]
    WriteError(String),

    #[error("deserialize error: {0}")]
    Serialize(#[from] crate::serialize::Error),

    #[error("join error: {0}")]
    Join(#[from] tokio::task::JoinError),

    #[error("object store error: {0}")]
    ObjectStoreError(#[from] ::object_store::Error),

    #[error("wal is shutdown and not accepting writes")]
    Shutdown,

    #[error("invalid gen1 duration {0}. Must be one of 1m, 5m, 10m")]
    InvalidGen1Duration(String),

    #[error("invalid WAL file path")]
    InvalidWalFilePath,
}

pub type Result<T, E = Error> = std::result::Result<T, E>;

#[async_trait]
pub trait Wal: Debug + Send + Sync + 'static {
    /// Buffer writes ops into the buffer, but returns before the operation is persisted to the WAL.
    async fn write_ops_unconfirmed(&self, op: Vec<WalOp>) -> Result<(), Error>;

    /// Writes the ops into the buffer and waits until the WAL file is persisted. When this returns
    /// the operations are durable in the configured object store and the file notifier has been
    /// called, which puts it into the queryable memory buffer.
    async fn write_ops(&self, ops: Vec<WalOp>) -> Result<(), Error>;

View on GitHub (pinned to 06200ef96b)