hashicorp/nomad · error

failed to convert username to UTF-16: %w

Error message

failed to convert username to UTF-16: %w

What it means

createUserToken converts the username to a NUL-terminated UTF-16 pointer required by the Win32 LogonUserW API. syscall.UTF16PtrFromString fails only if the string contains an interior NUL byte (or is too large); the error is wrapped so the caller knows username encoding failed before any logon attempt.

Source

Thrown at drivers/shared/executor/executor_windows.go:84

	}, cmd.SysProcAttr)

	return nil
}

var (
	advapiDll      = windows.NewLazySystemDLL("advapi32.dll")
	procLogonUserW = advapiDll.NewProc("LogonUserW")
)

const (
	_LOGON_SERVICE    uint32 = 5
	_PROVIDER_DEFAULT uint32 = 0
)

func createUserToken(domain, username string) (*syscall.Token, error) {
	userw, err := syscall.UTF16PtrFromString(username)
	if err != nil {
		return nil, fmt.Errorf("failed to convert username to UTF-16: %w", err)
	}
	domainw, err := syscall.UTF16PtrFromString(domain)
	if err != nil {
		return nil, fmt.Errorf("failed to convert user domain to UTF-16: %w", err)
	}
	var token syscall.Token
	ret, _, e := procLogonUserW.Call(
		uintptr(unsafe.Pointer(userw)),
		uintptr(unsafe.Pointer(domainw)),
		uintptr(unsafe.Pointer(nil)),
		uintptr(_LOGON_SERVICE),
		uintptr(_PROVIDER_DEFAULT),
		uintptr(unsafe.Pointer(&token)),
	)
	if ret == 0 {
		return nil, e
	}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Inspect the task's user value for embedded NUL/control characters and correct its source.
  2. Sanitize the user string (strip non-printable characters) before passing it to the executor.
  3. Correct the job spec so the username is plain text, e.g. 'DOMAIN\\user'.

Example fix

// before
user = strings.TrimSuffix(raw, "\x00") // still contains \x00 inside
// after
user = strings.Map(func(r rune) rune { if r == 0 { return -1 }; return r }, raw)
Defensive patterns

Strategy: validation

Validate before calling

// Go: reject usernames containing NUL before calling the executor
if strings.ContainsRune(username, 0) {
    return errors.New("username must not contain NUL bytes")
}

Type guard

func utf16Safe(s string) bool {
    _, err := syscall.UTF16PtrFromString(s)
    return err == nil
}

Try / catch

if err := exec.SetUser(cmd, user); err != nil {
    if strings.Contains(err.Error(), "convert username to UTF-16") {
        return fmt.Errorf("malformed username (control chars?) in %q", user)
    }
    return err
}

Prevention

When it happens

Trigger: The username passed to createUserToken contains a '\x00' character — practically only via programmatically supplied user strings rather than normal config.

Common situations: Corrupted job spec or templated user value injecting a NUL; binary data misinterpreted as a username from a misbehaving driver/plugin.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/259368682abdf72d. Report an issue: GitHub.