{"record":{"id":"f72527cc85aa0184","repo":"influxdata/influxdb","slug":"duration-not-to-overflow-v2","errorCode":null,"errorMessage":"duration not to overflow","messagePattern":"duration not to overflow","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"influxdb3_catalog/src/catalog/versions/v2.rs","lineNumber":1044,"sourceCode":"    pub async fn create_named_admin_token_with_permission(\n        &self,\n        token_name: String,\n        expiry_secs: Option<u64>,\n    ) -> Result<(Arc<TokenInfo>, String)> {\n        let (token, hash) = create_token_and_hash();\n        self.catalog_update_with_retry(|| {\n            if self.inner.read().tokens.repo().contains_name(&token_name) {\n                return Err(CatalogError::TokenNameAlreadyExists(token_name.clone()));\n            }\n\n            let (token_id, created_at, expiry) = {\n                let mut inner = self.inner.write();\n                let token_id = inner.tokens.get_and_increment_next_id();\n                let created_at = self.time_provider.now();\n                let expiry = expiry_secs.map(|secs| {\n                    created_at\n                        .checked_add(Duration::from_secs(secs))\n                        .expect(\"duration not to overflow\")\n                        .timestamp_millis()\n                });\n                (token_id, created_at.timestamp_millis(), expiry)\n            };\n\n            Ok(CatalogBatch::Token(TokenBatch {\n                time_ns: created_at,\n                ops: vec![TokenCatalogOp::CreateAdminToken(CreateAdminTokenDetails {\n                    token_id,\n                    name: Arc::from(token_name.as_str()),\n                    hash: hash.clone(),\n                    created_at,\n                    updated_at: None,\n                    expiry,\n                })],\n            }))\n        })\n        .await?;","sourceCodeStart":1026,"sourceCodeEnd":1062,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_catalog/src/catalog/versions/v2.rs#L1026-L1062","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Reduce the token expiry seconds to a sane bound (e.g. <= 253402300799, max representable timestamp).","Validate/clamp expiry_secs before calling the creation API (e.g. cap at 100 years).","If 'never expire' is intended, pass None/omit expiry rather than a huge number of seconds.","Fix the config value or script that computes the TTL to use the correct unit and magnitude.","Upgrade to a version where the API returns a typed error instead of panicking, if available."],"exampleFix":"// before\nlet expiry_secs = u64::MAX; // from misconfigured TTL\ncreate_token(name, Some(expiry_secs));\n// after\nconst MAX_EXPIRY_SECS: u64 = 253_402_300_799; // year 9999\nlet expiry_secs = expiry_secs.min(MAX_EXPIRY_SECS);\ncreate_token(name, Some(expiry_secs));","handlingStrategy":"validation","validationCode":"const MAX_EXPIRY_SECS: u64 = 253_402_300_799; // year 9999\nlet expiry_secs = match expiry_secs {\n    s if s > MAX_EXPIRY_SECS => return Err(format!(\"expiry {s}s too large\")),\n    s => s,\n};","typeGuard":"fn valid_expiry(secs: Option<u64>) -> bool {\n    secs.map(|s| s > 0 && s <= 253_402_300_799).unwrap_or(true)\n}","tryCatchPattern":"if !valid_expiry(expiry_secs) {\n    return Err(\"token expiry out of representable range\");\n}\n// The library panics on overflow, so pre-validate rather than catching.","preventionTips":["Clamp token TTLs to sane maximums (e.g. 10 years)","Pass None instead of huge sentinel values for 'no expiry'","Audit config files/scripts for unit mistakes (ms vs s)","Validate user-supplied expiry at the API boundary"],"tags":["panic","duration","overflow","token"],"backgroundTag":"argument-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"}