{"record":{"id":"600a2d743be1609a","repo":"hashicorp/nomad","slug":"failed-to-convert-s-to-utf16-v","errorCode":null,"errorMessage":"failed to convert \"%s\" to UTF16: %v","messagePattern":"failed to convert \"(.+?)\" to UTF16: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/fingerprint/storage_windows.go","lineNumber":28,"sourceCode":")\n\n//go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zstorage_windows.go storage_windows.go\n\n//sys\tgetDiskSpaceEx(dirName *uint16, availableFreeBytes *uint64, totalBytes *uint64, totalFreeBytes *uint64) (err error) = kernel32.GetDiskFreeSpaceExW\n\n// diskInfo inspects the filesystem for path and returns the volume name and\n// the total bytes available on the file system.\nfunc (f *StorageFingerprint) diskInfo(path string) (volume string, total uint64, err error) {\n\tabsPath, err := filepath.Abs(path)\n\tif err != nil {\n\t\treturn \"\", 0, fmt.Errorf(\"failed to determine absolute path for %s\", path)\n\t}\n\n\tvolume = filepath.VolumeName(absPath)\n\n\tabsPathp, err := syscall.UTF16PtrFromString(absPath)\n\tif err != nil {\n\t\treturn \"\", 0, fmt.Errorf(\"failed to convert \\\"%s\\\" to UTF16: %v\", absPath, err)\n\t}\n\n\tif err := getDiskSpaceEx(absPathp, nil, &total, nil); err != nil {\n\t\treturn \"\", 0, fmt.Errorf(\"failed to get free disk space for %s: %v\", absPath, err)\n\t}\n\n\treturn volume, total, nil\n}\n","sourceCodeStart":10,"sourceCodeEnd":37,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/client/fingerprint/storage_windows.go#L10-L37","documentation":"After resolving the absolute path, diskInfo() converts it to a UTF-16 pointer via syscall.UTF16PtrFromString, required by the Windows API. This error is returned when the conversion fails — almost always because the path contains an embedded NUL byte (\\x00), which Windows strings cannot carry.","triggerScenarios":"Storage fingerprint on Windows where syscall.UTF16PtrFromString(absPath) errors, typically because the volume path string contains a NUL byte.","commonSituations":"Path data read from config or environment carries a stray NUL byte; a driver or plugin returns a malformed path; heap-corruption-adjacent string bugs surfacing as 'invalid argument'.","solutions":["Sanitize the volume path to remove NUL bytes before it reaches the fingerprint (strings.ReplaceAll(p, \"\\x00\", \"\"))","Check where the path originates (config file, env var, plugin output) and fix the producer of the malformed string","Re-run the fingerprint with a simple known-good path like 'C:\\\\' to confirm the host is healthy"],"exampleFix":"// before\npath := someConfiguredPath // may contain \"\\x00\"\n// after\npath := strings.ReplaceAll(someConfiguredPath, \"\\x00\", \"\")","handlingStrategy":"validation","validationCode":"if strings.ContainsRune(path, '\\x00') {\n    return fmt.Errorf(\"volume path %q contains NUL byte and cannot be converted to UTF16\", path)\n}\nif _, err := syscall.UTF16FromString(path); err != nil {\n    return fmt.Errorf(\"path %q is not valid for Windows APIs: %v\", path, err)\n}","typeGuard":"func isUTF16SafePath(p string) bool {\n    _, err := syscall.UTF16FromString(p)\n    return err == nil\n}","tryCatchPattern":"volume, total, err := fp.diskInfo(path)\nif err != nil {\n    if strings.Contains(err.Error(), \"to UTF16\") {\n        log.Printf(\"malformed volume path %q, sanitizing\", path)\n        return fp.diskInfo(strings.ReplaceAll(path, \"\\x00\", \"\"))\n    }\n    return err\n}","preventionTips":["Never build paths via byte-slices that may carry trailing NUL bytes","Prefer utf16-safe helpers (golang.org/x/sys/windows) over raw syscall strings","Log the raw path bytes when path-related errors occur to spot hidden NULs"],"tags":["windows","encoding","utf16","fingerprinting"],"backgroundTag":"invalid-path-characters","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}