{"record":{"id":"fb7d1caf5992c486","repo":"gofiber/fiber","slug":"session-absolutetimeout-must-be-greater-than-or","errorCode":null,"errorMessage":"[session] AbsoluteTimeout must be greater than or equal to IdleTimeout","messagePattern":"\\[session\\] AbsoluteTimeout must be greater than or equal to IdleTimeout","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/session/config.go","lineNumber":147,"sourceCode":"//\tcfg := configDefault()\n//\tcfg := configDefault(customConfig)\nfunc configDefault(config ...Config) Config {\n\t// Return default config if nothing provided\n\tif len(config) < 1 {\n\t\treturn ConfigDefault\n\t}\n\n\t// Override default config\n\tcfg := config[0]\n\n\t// Set default values\n\tif cfg.IdleTimeout <= 0 {\n\t\tcfg.IdleTimeout = ConfigDefault.IdleTimeout\n\t}\n\n\t// Ensure AbsoluteTimeout is greater than or equal to IdleTimeout.\n\tif cfg.AbsoluteTimeout > 0 && cfg.AbsoluteTimeout < cfg.IdleTimeout {\n\t\tpanic(\"[session] AbsoluteTimeout must be greater than or equal to IdleTimeout\")\n\t}\n\n\t// Check if we have a zero-value Extractor\n\tif cfg.Extractor.Extract == nil {\n\t\tcfg.Extractor = ConfigDefault.Extractor\n\t}\n\n\tif cfg.KeyGenerator == nil {\n\t\tcfg.KeyGenerator = ConfigDefault.KeyGenerator\n\t}\n\n\tif cfg.CookieSameSite == \"\" {\n\t\tcfg.CookieSameSite = ConfigDefault.CookieSameSite\n\t}\n\n\treturn cfg\n}\n","sourceCodeStart":129,"sourceCodeEnd":165,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/session/config.go#L129-L165","documentation":"The session middleware enforces that AbsoluteTimeout (a hard cap on session lifetime) is at least as long as IdleTimeout (the inactivity window). An AbsoluteTimeout shorter than IdleTimeout is logically inconsistent — the session could never reach its idle window before being killed by the absolute cap — so configDefault panics. AbsoluteTimeout == 0 means \"no absolute cap\" and is explicitly allowed, so the panic only fires when AbsoluteTimeout is a positive value smaller than IdleTimeout.","triggerScenarios":"session.New(session.Config{IdleTimeout: 30 * time.Minute, AbsoluteTimeout: 5 * time.Minute}) — a 5-minute hard cap beneath a 30-minute idle window.","commonSituations":"Tuning session timeouts during security hardening; copy-pasting durations between the two fields; a unit mismatch (e.g. passing seconds to AbsoluteTimeout and minutes to IdleTimeout); shortening AbsoluteTimeout for compliance without also lowering IdleTimeout.","solutions":["Set AbsoluteTimeout >= IdleTimeout, or leave AbsoluteTimeout at 0 (no hard cap).","If you need a short hard cap, lower IdleTimeout to match or fall below it.","Centralize timeout values in named constants so both fields stay consistent."],"exampleFix":"// before\nsession.New(session.Config{\n    IdleTimeout:    30 * time.Minute,\n    AbsoluteTimeout: 5 * time.Minute, // panics\n})\n\n// after\nconst (\n    sessionIdle     = 30 * time.Minute\n    sessionAbsolute = 8 * time.Hour\n)\nsession.New(session.Config{\n    IdleTimeout:     sessionIdle,\n    AbsoluteTimeout: sessionAbsolute, // >= IdleTimeout, OK\n})","handlingStrategy":"validation","validationCode":"func validateSessionConfig(cfg session.Config) error {\n    idle := cfg.IdleTimeout\n    if idle <= 0 { idle = 30 * time.Minute } // mirrors configDefault\n    if cfg.AbsoluteTimeout > 0 && cfg.AbsoluteTimeout < idle {\n        return fmt.Errorf(\"AbsoluteTimeout (%s) < IdleTimeout (%s)\", cfg.AbsoluteTimeout, idle)\n    }\n    return nil\n}\n// if err := validateSessionConfig(cfg); err != nil { log.Fatal(err) }","typeGuard":"func sessionTimeoutsConsistent(cfg session.Config) bool {\n    idle := cfg.IdleTimeout\n    if idle <= 0 { idle = 30 * time.Minute }\n    return cfg.AbsoluteTimeout == 0 || cfg.AbsoluteTimeout >= idle\n}","tryCatchPattern":null,"preventionTips":["Derive both timeouts from a small set of named constants so they cannot drift.","Add a config-validation step in your bootstrap that runs before session.New.","Watch for unit mismatches (time.Second vs time.Minute) when copying values between the two fields."],"tags":["session","config","panic","middleware"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}