{"record":{"id":"72efadadee629022","repo":"gofiber/fiber","slug":"cors-invalid-origin-format-in-configuration","errorCode":null,"errorMessage":"[CORS] Invalid origin format in configuration: ","messagePattern":"\\[CORS\\] Invalid origin format in configuration: ","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/cors/cors.go","lineNumber":73,"sourceCode":"\t// allowOrigins is a set of strings that contains the allowed origins\n\t// defined in the 'AllowOrigins' configuration.\n\tallowOrigins := make(map[string]struct{}, len(cfg.AllowOrigins))\n\tallowSubOrigins := []subdomain{}\n\n\t// Validate and normalize static AllowOrigins\n\tallowAllOrigins := len(cfg.AllowOrigins) == 0 && cfg.AllowOriginsFunc == nil\n\tfor _, origin := range cfg.AllowOrigins {\n\t\tif origin == \"*\" {\n\t\t\tallowAllOrigins = true\n\t\t\tbreak\n\t\t}\n\n\t\ttrimmedOrigin := utils.TrimSpace(origin)\n\t\tif before, after, found := strings.Cut(trimmedOrigin, \"://*.\"); found {\n\t\t\twithoutWildcard := before + \"://\" + after\n\t\t\tisValid, normalizedOrigin := normalizeOrigin(withoutWildcard)\n\t\t\tif !isValid {\n\t\t\t\tpanic(\"[CORS] Invalid origin format in configuration: \" + maskValue(trimmedOrigin))\n\t\t\t}\n\t\t\tscheme, host, ok := strings.Cut(normalizedOrigin, \"://\")\n\t\t\tif !ok {\n\t\t\t\tpanic(\"[CORS] Invalid origin format after normalization:\" + maskValue(trimmedOrigin))\n\t\t\t}\n\t\t\tsd := subdomain{prefix: scheme + \"://\", suffix: host}\n\t\t\tallowSubOrigins = append(allowSubOrigins, sd)\n\t\t} else {\n\t\t\tisValid, normalizedOrigin := normalizeOrigin(trimmedOrigin)\n\t\t\tif !isValid {\n\t\t\t\tpanic(\"[CORS] Invalid origin format in configuration: \" + maskValue(trimmedOrigin))\n\t\t\t}\n\t\t\tallowOrigins[normalizedOrigin] = struct{}{}\n\t\t}\n\t}\n\n\t// Validate CORS credentials configuration\n\tif cfg.AllowCredentials && allowAllOrigins {","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/cors/cors.go#L55-L91","documentation":"In the CORS middleware, an AllowOrigins entry containing the wildcard-subdomain marker '://*.' (e.g. 'https://*.example.com') is rewritten by removing the wildcard and then validated via normalizeOrigin. If normalizeOrigin rejects it (unparseable URL, userinfo present, empty host, embedded '*' in host, or a path/query/fragment other than a root '/'), the config is invalid and CORS startup panics. The offending value is masked in the message (maskValue) to avoid leaking secrets embedded in origins.","triggerScenarios":"cors.New(cors.Config{ AllowOrigins: []string{\"https://*.example.com/path\", \"https://*:8080\", \"https://*.\" } }) — any '://*.' origin whose non-wildcard portion fails normalizeOrigin. Examples: missing host after the wildcard, an appended path/query, a port attached to the wildcard, or a fragment.","commonSituations":"Typing a path or port after a wildcard subdomain ('https://*.app.com/api'); using 'https://*' (wildcard with no base domain); embedding credentials/userinfo; copy-pasting a full Origin header that includes a trailing path or query.","solutions":["For wildcard subdomains use the exact form 'https://*.example.com' with no path, query, fragment, or port on the wildcard portion.","If you need to allow specific paths, do it in your handler/route logic, not in AllowOrigins (origins are scheme+host only).","Validate each AllowOrigins entry with net/url.Parse before constructing the Config."],"exampleFix":"// before\ncors.New(cors.Config{ AllowOrigins: []string{\"https://*.example.com/api\"} })\n// after\ncors.New(cors.Config{ AllowOrigins: []string{\"https://*.example.com\"} })","handlingStrategy":"validation","validationCode":"func validWildcardOrigin(o string) bool {\n    before, after, found := strings.Cut(strings.TrimSpace(o), \"://*.\")\n    if !found {\n        return false\n    }\n    u, err := url.Parse(before + \"://\" + after)\n    if err != nil || u.User != nil || u.Host == \"\" ||\n        strings.Contains(u.Host, \"*\") ||\n        (u.Path != \"\" && u.Path != \"/\") || u.RawQuery != \"\" || u.Fragment != \"\" {\n        return false\n    }\n    return true\n}\nfor _, o := range cfg.AllowOrigins {\n    if strings.Contains(o, \"://*.\") && !validWildcardOrigin(o) {\n        return fmt.Errorf(\"invalid wildcard origin %q\", o)\n    }\n}","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        log.Fatalf(\"CORS origin rejected: %v\", r)\n    }\n}()\ncors.New(cfg)","preventionTips":["Format wildcard origins as 'https://*.example.com' with no path/query/port.","Validate every AllowOrigins entry with url.Parse before constructing Config.","Keep origins scheme+host only; move path logic into routes."],"tags":["middleware","cors","config","validation","security","startup"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}