JanDeDobbeleer/oh-my-posh · error

unable to add font resource using AddFontResourceW

Error message

unable to add font resource using AddFontResourceW

What it means

The final step of the Windows font install calls the Win32 AddFontResourceW API via syscall to make the font available in the current session. If the call returns 0, the font resource was not added, and install returns this error. At this point the registry entry was already written, so the font is registered but not loaded until reboot/logoff.

Source

Thrown at src/cli/font/install_windows.go:141

	if err = k.SetStringValue(fontName, regValue); err != nil {
		log.Error(err)
		// If this fails, remove the font file as well.
		if nexterr := os.Remove(fullPath); nexterr != nil {
			return errors.New("unable to delete font file after registry key set error")
		}

		return fmt.Errorf("unable to set registry value: %s", err.Error())
	}

	fontPtr, err := syscall.UTF16PtrFromString(fullPath)
	if err != nil {
		return err
	}

	ret, _, _ := addFontResourceW.Call(uintptr(unsafe.Pointer(fontPtr)))
	if ret == 0 {
		return errors.New("unable to add font resource using AddFontResourceW")
	}

	log.Debug("font resource added successfully")

	return nil
}

View on GitHub (pinned to 0976794618)

Solutions

  1. Verify the extracted file is a valid .ttf/.otf (try opening it in the Windows font viewer).
  2. Re-download/reinstall the font to rule out a corrupt archive.
  3. Reboot or sign out/in — the registry entry exists, so the font may load in a new session even if AddFontResourceW failed.
  4. Retry the install after confirming the font path contains no unusual characters.
Defensive patterns

Strategy: fallback

Validate before calling

// verify the file is a parseable font before installing
data, err := os.ReadFile(fullPath)
if err != nil || len(data) < 4 {
    return errors.New("font file missing or truncated")
}
// ttf: \x00\x01\x00\x00 ; otf: 'OTTO'
if !bytes.HasPrefix(data, []byte{0, 1, 0, 0}) && !bytes.HasPrefix(data, []byte("OTTO")) {
    return errors.New("not a valid ttf/otf file")
}

Try / catch

if err := font.Install(env, name, report); err != nil {
    if strings.Contains(err.Error(), "AddFontResourceW") {
        log.Printf("font registered in registry but not loaded this session; a reboot/logoff will activate it")
        return nil // registry entry exists; treat as soft success
    }
    return err
}

Prevention

When it happens

Trigger: addFontResourceW.Call with the UTF-16 pointer to the font file path returns 0 — invalid or non-font file content, path issues, or GDI failing to load the font file in the current session.

Common situations: Downloaded/extracted archive contained a corrupt or unsupported font file; file path with unexpected characters; GDI resource exhaustion; the file was modified or truncated after registration.

Related errors


AI-assisted analysis of JanDeDobbeleer/oh-my-posh@0976794618 (2026-08-31). Data as JSON: /api/errors/807751ae5a4e3fe8. Report an issue: GitHub.