{"id":"03c044cb4beb19ef","repo":"gofiber/fiber","slug":"helmet-hstspreloadenabled-requires-hstsexcludesub","errorCode":null,"errorMessage":"helmet: HSTSPreloadEnabled requires HSTSExcludeSubdomains to be false","messagePattern":"helmet: HSTSPreloadEnabled requires HSTSExcludeSubdomains to be false","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"middleware/helmet/config.go","lineNumber":114,"sourceCode":"\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}\n\n\tif cfg.ReferrerPolicy == \"\" {\n\t\tcfg.ReferrerPolicy = ConfigDefault.ReferrerPolicy\n\t}","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/middleware/helmet/config.go#L96-L132","documentation":"The HSTS preload list (hstspreload.org) requires that preloaded domains include subdomains — you cannot submit a domain for preload while excluding subdomains. configDefault (helmet/config.go:113-115) panics when both HSTSPreloadEnabled and HSTSExcludeSubdomains are true, preventing a header combination the preload list would reject.","triggerScenarios":"Setting helmet.Config{HSTSPreloadEnabled: true, HSTSExcludeSubdomains: true}. The combination is invalid per the HSTS preload submission requirements.","commonSituations":"Turning on preload for SEO/security hardening while keeping HSTSExcludeSubdomains true from a previous config that hosts untrusted subdomains. Also: copy-pasting a hardened config without reconciling the two flags.","solutions":["If you want preload, set HSTSExcludeSubdomains: false so all subdomains are covered.","If you must exclude subdomains, set HSTSPreloadEnabled: false.","Ensure HSTSMaxAge is at least 1 year (31536000) before enabling preload — the preload list requires it."],"exampleFix":"// before\nhelmet.New(helmet.Config{HSTSPreloadEnabled: true, HSTSExcludeSubdomains: true})\n\n// after\nhelmet.New(helmet.Config{\n    HSTSMaxAge:            31536000,\n    HSTSPreloadEnabled:    true,\n    HSTSExcludeSubdomains: false,\n})","handlingStrategy":"validation","validationCode":"func validateHelmetPreload(cfg helmet.Config) error {\n    if cfg.HSTSPreloadEnabled && cfg.HSTSExcludeSubdomains {\n        return errors.New(\"HSTSPreloadEnabled requires HSTSExcludeSubdomains=false\")\n    }\n    if cfg.HSTSPreloadEnabled && cfg.HSTSMaxAge < 31536000 {\n        return errors.New(\"HSTS preload requires MaxAge >= 1 year (31536000)\")\n    }\n    return nil\n}\n\nif err := validateHelmetPreload(cfg); err != nil { log.Fatal(err) }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat preload as a commit-time decision; it is not easily reversible.","Keep HSTSExcludeSubdomains false whenever preload is enabled."],"tags":["helmet","hsts","preload","security","config","panic"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}