{"record":{"id":"63ceb98919cf0f83","repo":"gohugoio/hugo","slug":"cannot-create-s-windows-filename-restriction","errorCode":null,"errorMessage":"cannot create \"%s\": Windows filename restriction","messagePattern":"cannot create \"(.+?)\": Windows filename restriction","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hugolib/alias.go","lineNumber":172,"sourceCode":"\t\t\tcontinue\n\t\t}\n\t}\n\tfor _, comp := range components {\n\t\tif strings.HasSuffix(comp, \" \") || strings.HasSuffix(comp, \".\") {\n\t\t\tmsgs = append(msgs, fmt.Sprintf(\"Alias \\\"%s\\\" contains component with a trailing space or period, problematic on Windows\", originalAlias))\n\t\t}\n\t\tfor _, r := range reservedNames {\n\t\t\tif comp == r {\n\t\t\t\tmsgs = append(msgs, fmt.Sprintf(\"Alias \\\"%s\\\" contains component with reserved name \\\"%s\\\" on Windows\", originalAlias, r))\n\t\t\t}\n\t\t}\n\t}\n\tif len(msgs) > 0 {\n\t\tif runtime.GOOS == \"windows\" {\n\t\t\tfor _, m := range msgs {\n\t\t\t\ta.log.Errorln(m)\n\t\t\t}\n\t\t\treturn \"\", fmt.Errorf(\"cannot create \\\"%s\\\": Windows filename restriction\", originalAlias)\n\t\t}\n\t\tfor _, m := range msgs {\n\t\t\ta.log.Infoln(m)\n\t\t}\n\t}\n\n\t// Add the final touch. When the alias does not already end in one of the\n\t// output format's configured suffixes, treat it as a directory and append\n\t// the format's base name and suffix (e.g. index.html).\n\talias = strings.TrimPrefix(alias, \"/\")\n\tbaseFile := of.BaseName + of.MediaType.FirstSuffix.FullSuffix\n\tif strings.HasSuffix(alias, \"/\") {\n\t\talias = alias + baseFile\n\t} else if !pathHasOutputFormatSuffix(alias, of) {\n\t\talias = alias + \"/\" + baseFile\n\t}\n\n\treturn filepath.FromSlash(alias), nil","sourceCodeStart":154,"sourceCodeEnd":190,"githubUrl":"https://github.com/gohugoio/hugo/blob/52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2/hugolib/alias.go#L154-L190","documentation":"Returned by targetPathAlias only on Windows (runtime.GOOS == \"windows\") when the alias fails one or more Windows filename checks: reserved device names (CON, PRN, AUX, NUL, COM1-9, LPT1-9), forbidden characters (: * ? \\\" < > |), ASCII control chars (0x00-0x1F), or components with trailing space/period. The individual problems are logged via Errorln first, then the aggregate error is returned. On non-Windows the same problems are only logged as Info and the alias proceeds.","triggerScenarios":"Building on Windows with a front-matter alias containing a Windows-reserved name or forbidden char, e.g. aliases: [\"aux\"], aliases: [\"a:b\"], aliases: [\"file.\"] — the publish step then aborts for that alias. Cross-platform teams hit it when a Linux/macOS-authored alias is fine there but fails on a Windows CI/colleague.","commonSituations":"Aliases with colons (common in some URL schemes), trailing dots, reserved device names, or question marks; content authored on case-sensitive OSes reaching a Windows builder; CI matrix that includes windows-latest.","solutions":["Rename the alias to avoid reserved device names and the chars : * ? \\\" < > | and trailing space/period.","Move the build off Windows for affected aliases, or pre-process aliases to sanitize Windows-illegal components.","Add a pre-build lint that rejects Windows-invalid alias segments regardless of build OS."],"exampleFix":"---\n# before (fails on Windows)\naliases:\n  - \"help:nlp\"\n# after\naliases:\n  - \"help-nlp\"\n---","handlingStrategy":"validation","validationCode":"var reserved = []string{\"CON\",\"PRN\",\"AUX\",\"NUL\",\"COM0\",\"COM1\",\"COM2\",\"COM3\",\"COM4\",\"COM5\",\"COM6\",\"COM7\",\"COM8\",\"COM9\",\"LPT0\",\"LPT1\",\"LPT2\",\"LPT3\",\"LPT4\",\"LPT5\",\"LPT6\",\"LPT7\",\"LPT8\",\"LPT9\"}\nfunc windowsSafeAlias(a string) error {\n    if strings.ContainsAny(a, `:*?\\\"<>|`) { return fmt.Errorf(\"bad char\") }\n    for _, c := range strings.Split(path.Clean(filepath.ToSlash(a)), \"/\") {\n        for _, r := range reserved { if c == r { return fmt.Errorf(\"reserved\") } }\n        if strings.TrimRight(c, \" .\") != c { return fmt.Errorf(\"trailing space/dot\") }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate aliases against Windows rules even when building on Unix, for portability.","Avoid colons, reserved device names, and trailing dots/spaces in aliases.","Add a CI lint that runs the windowsSafeAlias check on all front matter."],"tags":["alias","windows","filename-restriction","cross-platform","hugolib"],"backgroundTag":null,"analyzedSha":"52c9bd7908b4d02d4d0ff8f82a888834d6ee10d2","analyzedAt":"2026-08-09T21:49:36.660Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}