As I understand it the zip file should live in /srv/salt/_modules/ as I am have done. This bug should be refocused on zip delivery. Tim's suggestion seems against the documentation, https://docs.saltstack.com/en/latest/ref/modules/ but works, so the documentation should also be updated. I expended the module in _modules and with some fiddling got it to run. salt:/srv/salt # salt '*' saltutil.sync_modules linux-2grp.fritz.box: - modules.sesceph.__init__ linux-geds.fritz.box: - modules.sesceph.__init__ salt-deb.yokel.org: - modules.sesceph.__init__ - modules.sesceph.__init__ salt:/srv/salt # cat _modules/sesceph/__init__.py import logging log = logging.getLogger(__name__) __virtualname__ = 'sesceph' def is_ok(): ''' A function to make some spam with eggs! CLI Example:: salt '*' test.spam eggs ''' log.error('wibble') return {"one" : "two" } def __virtual__(): return __virtualname__ salt:/srv/salt # salt '*' sesceph.is_ok [ERROR ] Invalid outputter is_ok specified, fall back to nested salt-deb.yokel.org: ---------- one: two linux-2grp.fritz.box: ---------- one: two linux-geds.fritz.box: ---------- one: two