{"record":{"id":"e762b6c032609be6","repo":"gofiber/fiber","slug":"helmet-hstsmaxage-must-be-greater-than-or-equal-t","errorCode":null,"errorMessage":"helmet: HSTSMaxAge must be greater than or equal to 0","messagePattern":"helmet: HSTSMaxAge must be greater than or equal to 0","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/helmet/config.go","lineNumber":110,"sourceCode":"\tCrossOriginResourcePolicy: \"same-origin\",\n\tOriginAgentCluster:        \"?1\",\n\tXDNSPrefetchControl:       \"off\",\n\tXDownloadOptions:          \"noopen\",\n\tXPermittedCrossDomain:     \"none\",\n}\n\n// Helper function to set default values\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\tif cfg.HSTSMaxAge < 0 {\n\t\tpanic(\"helmet: HSTSMaxAge must be greater than or equal to 0\")\n\t}\n\n\tif cfg.HSTSPreloadEnabled && cfg.HSTSExcludeSubdomains {\n\t\tpanic(\"helmet: HSTSPreloadEnabled requires HSTSExcludeSubdomains to be false\")\n\t}\n\n\t// Set default values\n\tif cfg.XSSProtection == \"\" {\n\t\tcfg.XSSProtection = ConfigDefault.XSSProtection\n\t}\n\n\tif cfg.ContentTypeNosniff == \"\" {\n\t\tcfg.ContentTypeNosniff = ConfigDefault.ContentTypeNosniff\n\t}\n\n\tif cfg.XFrameOptions == \"\" {\n\t\tcfg.XFrameOptions = ConfigDefault.XFrameOptions\n\t}","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/helmet/config.go#L92-L128","documentation":"The helmet middleware panics during configDefault when Config.HSTSMaxAge is negative. HSTS max-age is emitted verbatim into the Strict-Transport-Security header (e.g. max-age=31536000) and per RFC 6797 it must be a non-negative integer of seconds. A negative value is nonsensical and would produce an invalid header, so helmet fails fast at startup rather than shipping a broken security directive.","triggerScenarios":"Passing helmet.Config{HSTSMaxAge: -1} (or any value < 0) to helmet.New. Common when HSTSMaxAge is derived from an int subtraction (e.g. someConstant - delta) that underflows, or when a -1 is used as a 'disabled' sentinel.","commonSituations":"Loading max-age from an env var parsed as a signed int where the env var is unset and defaults to -1; computing max-age as an expiry offset that goes negative near token expiration; copy-pasting a config block and forgetting to set the field (Go zero-value 0 is fine, so this only fires on an explicit negative).","solutions":["Set HSTSMaxAge to 0 (Go zero value) to effectively disable HSTS, or to a positive duration in seconds such as 31536000 (one year).","If the value is computed, clamp it before passing to helmet.New: if v < 0 { v = 0 }.","If loading from configuration, validate the parsed int and treat unparseable/negative input as a config-load error rather than forwarding it to helmet."],"exampleFix":"// before\napp.Use(helmet.New(helmet.Config{\n    HSTSMaxAge: expiry.Sub(time.Now()), // can be negative once expiry passes\n}))\n\n// after\nmaxAge := int(time.Until(expiry).Seconds())\nif maxAge < 0 {\n    maxAge = 0\n}\napp.Use(helmet.New(helmet.Config{\n    HSTSMaxAge: maxAge,\n}))","handlingStrategy":"validation","validationCode":"// before calling helmet.New\nfunc sanitizeHSTSMaxAge(v int) int {\n    if v < 0 {\n        return 0 // or return an error from your config loader\n    }\n    return v\n}\n\ncfg := helmet.Config{HSTSMaxAge: sanitizeHSTSMaxAge(parsedMaxAge)}\napp.Use(helmet.New(cfg))","typeGuard":"func isValidHSTSMaxAge(v int) bool { return v >= 0 }","tryCatchPattern":null,"preventionTips":["Never use -1 as a 'disabled' sentinel for HSTSMaxAge — use 0 to disable HSTS.","When computing max-age from a time delta, clamp the result to >= 0 before assigning.","Validate signed-int config values at the loader boundary, not at middleware construction."],"tags":["helmet","hsts","config","security-header","startup-panic"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}