influxdata/influxdb · error

duration not to overflow

Error message

duration not to overflow

What it means

This panic fires when computing a token's expiry: created_at + Duration::from_secs(secs) overflows the timestamp type, so checked_add returns None. It guards against absurdly large expiry values that cannot be represented as a millisecond timestamp.

Solutions

  1. Reduce the token expiry seconds to a sane bound (e.g. <= 253402300799, max representable timestamp).
  2. Validate/clamp expiry_secs before calling the creation API (e.g. cap at 100 years).
  3. If 'never expire' is intended, pass None/omit expiry rather than a huge number of seconds.
  4. Fix the config value or script that computes the TTL to use the correct unit and magnitude.
  5. Upgrade to a version where the API returns a typed error instead of panicking, if available.

Example fix

// before
let expiry_secs = u64::MAX; // from misconfigured TTL
create_token(name, Some(expiry_secs));
// after
const MAX_EXPIRY_SECS: u64 = 253_402_300_799; // year 9999
let expiry_secs = expiry_secs.min(MAX_EXPIRY_SECS);
create_token(name, Some(expiry_secs));
Defensive patterns

Strategy: validation

Validate before calling

const MAX_EXPIRY_SECS: u64 = 253_402_300_799; // year 9999
let expiry_secs = match expiry_secs {
    s if s > MAX_EXPIRY_SECS => return Err(format!("expiry {s}s too large")),
    s => s,
};

Type guard

fn valid_expiry(secs: Option<u64>) -> bool {
    secs.map(|s| s > 0 && s <= 253_402_300_799).unwrap_or(true)
}

Try / catch

if !valid_expiry(expiry_secs) {
    return Err("token expiry out of representable range");
}
// The library panics on overflow, so pre-validate rather than catching.

Prevention

When it happens

Trigger: Creating a token with an expiry_secs value so large (e.g. u64::MAX or many centuries of seconds) that adding it to the current time overflows DateTime/Duration arithmetic.

Common situations: Misconfigured token TTL in config files (raw seconds value typo'd or set to i64::MAX/u64::MAX); API callers passing an unvalidated 'never expire'-style sentinel as seconds; provisioning scripts computing TTL with wrong units.

Related errors


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

Appendix: source

Thrown at influxdb3_catalog/src/catalog/versions/v2.rs:1044

    pub async fn create_named_admin_token_with_permission(
        &self,
        token_name: String,
        expiry_secs: Option<u64>,
    ) -> Result<(Arc<TokenInfo>, String)> {
        let (token, hash) = create_token_and_hash();
        self.catalog_update_with_retry(|| {
            if self.inner.read().tokens.repo().contains_name(&token_name) {
                return Err(CatalogError::TokenNameAlreadyExists(token_name.clone()));
            }

            let (token_id, created_at, expiry) = {
                let mut inner = self.inner.write();
                let token_id = inner.tokens.get_and_increment_next_id();
                let created_at = self.time_provider.now();
                let expiry = expiry_secs.map(|secs| {
                    created_at
                        .checked_add(Duration::from_secs(secs))
                        .expect("duration not to overflow")
                        .timestamp_millis()
                });
                (token_id, created_at.timestamp_millis(), expiry)
            };

            Ok(CatalogBatch::Token(TokenBatch {
                time_ns: created_at,
                ops: vec![TokenCatalogOp::CreateAdminToken(CreateAdminTokenDetails {
                    token_id,
                    name: Arc::from(token_name.as_str()),
                    hash: hash.clone(),
                    created_at,
                    updated_at: None,
                    expiry,
                })],
            }))
        })
        .await?;

View on GitHub (pinned to 06200ef96b)