Thanks a lot for the tip. I don't know what was wrong with MSYS2 version of hunspell, but this one works with the following minimal configuration: (setq ispell-program-name (executable-find "hunspell")) (setq ispell-local-dictionary "en_US") (setq ispell-local-dictionary-alist '(("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil nil nil utf-8))) Nevertheless, I can still see ispell-phaf: No matching entry for nil So it still tries to call `ispell-parse-hunspell-affix-file' with `nil' for the first time, and only then calls it with "en_US" in my case. Secondly, I think that relying on "hunspell -D" so stubbornly that `ispell-parse-hunspell-affix-file' blocks all further usage of ispell.el with hunspell if `ispell-hunspell-dict-paths-alist' is just dumb. Here are a few reasons: 1. Not all distributions of hunspell even supply "share/hunspell/*" stuff with them; 2. Some users don't use dictionaries from "share/hunspell/*" because they might get either more updated dictionaries themselves and/or already have customized personal dictionaries. For instance, #2 is exactly what I was planning to do: (let ((dictionaries-dir (expand-file-name "dictionaries" user-emacs-directory))) (make-directory dictionaries-dir t) (setq ispell-local-dictionary "en_US") (setq ispell-local-dictionary-alist '((nil "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US" "-p" dictionaries-dir) nil utf-8) ("en_US" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "en_US" "-p" dictionaries-dir) nil utf-8) ("german" "[[:alpha:]]" "[^[:alpha:]]" "[']" t ("-d" "de_DE_frami" "-p" dictionaries-dir) "~tex" utf-8) ("russian" "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-d" "ru_RU" "-p" dictionaries-dir) nil utf-8))))) and in this case I obviously don't care at all whether hunspell has anything in "share/hunspell/*" or not. So why would I be forcefully blocked to use it with some weird error from `ispell-parse-hunspell-affix-file'? How about redesign?