ValueError: q must be exactly 160, 224, or 256 bits long
Describe the bug
Just starting with pyinfra. I'm trying to do an initial install. When trying to run pyinfra with below inventory.py or below cli command I get a 'ValueError: q must be exactly 160, 224, or 256 bits long' error.
To Reproduce
Steps to reproduce the behavior, please include where possible:
- Operation code & usage inventory.py
import getpass
import os
HOSTNAME = "olivar"
SSH_USER = "root" # e.g., 'ubuntu', 'admin', 'root'
hosts = [
(HOSTNAME, {
"ssh_user": SSH_USER,
"ssh_password": getpass.getpass(prompt=f"Password for {SSH_USER}@{HOSTNAME}: ")
}),
]
cli command
pyinfra --ssh-user="root" --ssh-password="mypw" myhost deploy.py
- Target system information current EndeavourOS (archlinux) on Lenovo T480
- Example using the
@dockerconnector (helps isolate the problem) don't want to install docker on this system if not absolutely necessary
Expected behavior
Have the command run without error and create inital users and install inital packages.
Meta
- Include output of
pyinfra --support.
If you are having issues with pyinfra or wish to make feature requests, please
check out the GitHub issues at https://github.com/Fizzadar/pyinfra/issues .
When adding an issue, be sure to include the following:
System: Linux
Platform: Linux-6.12.28-1-lts-x86_64-with-glibc2.41
Release: 6.12.28-1-lts
Machine: x86_64
pyinfra: v3.3.1
click: v8.1.8
coverage: v7.8.0
coverage: v7.8.0
distro: v1.9.0
gevent: v24.11.1
jinja2: v3.1.5
packaging: v25.0
paramiko: v3.5.0
pytest: v8.3.5
pytest: v8.3.5
python-dateutil: v2.9.0
pyyaml: v6.0.2
pyyaml: v6.0.2
setuptools: v80.3.1
typeguard: v4.4.2
typing-extensions: v4.13.2
wheel: v0.45.1
Executable: /usr/bin/pyinfra
Python: 3.13.3 (CPython, GCC 14.2.1 20250207)
- How was pyinfra installed (source/pip)? arch AUR
- Include pyinfra-debug.log (if one was created)
File "/usr/lib/python3.13/site-packages/pyinfra_cli/main.py", line 225, in cli
_main(*args, **kwargs)
~~~~~^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/pyinfra_cli/main.py", line 351, in _main
connect_all(state)
~~~~~~~~~~~^^^^^^^
File "/usr/lib/python3.13/site-packages/pyinfra/api/connect.py", line 37, in connect_all
greenlet.get()
~~~~~~~~~~~~^^
File "src/gevent/greenlet.py", line 797, in gevent._gevent_cgreenlet.Greenlet.get
File "src/gevent/greenlet.py", line 373, in gevent._gevent_cgreenlet.Greenlet._raise_exception
File "/usr/lib/python3.13/site-packages/gevent/_compat.py", line 50, in reraise
raise value.with_traceback(tb)
File "src/gevent/greenlet.py", line 900, in gevent._gevent_cgreenlet.Greenlet.run
File "/usr/lib/python3.13/site-packages/pyinfra/api/host.py", line 380, in connect
self.connector.connect()
^^^^^^^
File "/usr/lib/python3.13/site-packages/pyinfra/connectors/ssh.py", line 201, in connect
return self._connect()
^^^
File "/usr/lib/python3.13/site-packages/pyinfra/connectors/ssh.py", line 231, in _connect
self.client.connect(hostname, **kwargs)
^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/pyinfra/connectors/sshuserclient/client.py", line 182, in connect
super().connect(hostname, **config)
^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/paramiko/client.py", line 485, in connect
self._auth(
File "/usr/lib/python3.13/site-packages/paramiko/client.py", line 734, in _auth
self._transport.auth_publickey(username, key)
File "/usr/lib/python3.13/site-packages/paramiko/transport.py", line 1709, in auth_publickey
return self.auth_handler.wait_for_response(my_event)
^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/paramiko/auth_handler.py", line 248, in wait_for_response
raise e
File "/usr/lib/python3.13/site-packages/paramiko/transport.py", line 2262, in run
handler(m)
File "/usr/lib/python3.13/site-packages/paramiko/auth_handler.py", line 404, in _parse_service_accept
sig = self.private_key.sign_ssh_data(blob, algorithm)
^^^^^^^
File "/usr/lib/python3.13/site-packages/paramiko/dsskey.py", line 120, in sign_ssh_data
).private_key(backend=default_backend())
^^^^^^^^^^^^^^^
ValueError: q must be exactly 160, 224, or 256 bits long
- Consider including output with
-vvand--debug.
pyinfra --ssh-user="root" --ssh-password="thepw" thehost intial_install_deploy.py -vv --debug 23:45:45 [71/603]
--> Loading config...
--> Loading inventory...
[pyinfra_cli.inventory] Creating fake inventory...
[pyinfra_cli.inventory] Checking possible group_data at: /home/lvl/library/repos/pyinfra/group_data
--> Connecting to hosts...
[pyinfra.connectors.ssh] Connecting to: thehst ({'allow_agent': True, 'look_for_keys': True, '_pyinfra_ssh_forward_agent': False, '_pyinfra_ssh_config_file': None, '_pyinfra_ssh_known_hosts_file': None, '_pyinfra_ssh_strict_host_k
ey_checking': 'accept-new', '_pyinfra_ssh_paramiko_connect_kwargs': None, 'username': 'root', 'timeout': 10, 'password': 'pw'})
[pyinfra.connectors.sshuserclient.client] Loading SSH config: None
Unknown exception: q must be exactly 160, 224, or 256 bits long
Traceback (most recent call last):
File "/usr/lib/python3.13/site-packages/paramiko/transport.py", line 2262, in run
handler(m)
~~~~~~~^^^
File "/usr/lib/python3.13/site-packages/paramiko/auth_handler.py", line 404, in _parse_service_accept
sig = self.private_key.sign_ssh_data(blob, algorithm)
File "/usr/lib/python3.13/site-packages/paramiko/dsskey.py", line 120, in sign_ssh_data
).private_key(backend=default_backend())
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: q must be exactly 160, 224, or 256 bits long
Traceback (most recent call last):
File "src/gevent/greenlet.py", line 900, in gevent._gevent_cgreenlet.Greenlet.run
File "/usr/lib/python3.13/site-packages/pyinfra/api/host.py", line 380, in connect
self.connector.connect()
~~~~~~~~~~~~~~~~~~~~~~^^
File "/usr/lib/python3.13/site-packages/pyinfra/connectors/ssh.py", line 201, in connect
return self._connect()
~~~~~~~~~~~~~^^
File "/usr/lib/python3.13/site-packages/pyinfra/connectors/ssh.py", line 231, in _connect
self.client.connect(hostname, **kwargs)
~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/pyinfra/connectors/sshuserclient/client.py", line 182, in connect
super().connect(hostname, **config)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/paramiko/client.py", line 485, in connect
self._auth(
~~~~~~~~~~^
username,
^^^^^^^^^
...<9 lines>...
passphrase,
^^^^^^^^^^^
)
^
File "/usr/lib/python3.13/site-packages/paramiko/client.py", line 734, in _auth
self._transport.auth_publickey(username, key)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/paramiko/transport.py", line 1709, in auth_publickey
return self.auth_handler.wait_for_response(my_event)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/paramiko/auth_handler.py", line 248, in wait_for_response
raise e
File "/usr/lib/python3.13/site-packages/paramiko/transport.py", line 2262, in run
handler(m)
~~~~~~~^^^
File "/usr/lib/python3.13/site-packages/paramiko/auth_handler.py", line 404, in _parse_service_accept
sig = self.private_key.sign_ssh_data(blob, algorithm)
File "/usr/lib/python3.13/site-packages/paramiko/dsskey.py", line 120, in sign_ssh_data
).private_key(backend=default_backend())
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: q must be exactly 160, 224, or 256 bits long
2025-05-21T21:45:45Z <Greenlet at 0x75d121c77560: <bound method Host.connect of Host(olivar)>> failed with ValueError
--> Disconnecting from hosts...
--> An internal exception occurred:
File "/usr/lib/python3.13/site-packages/paramiko/dsskey.py", line 120, in sign_ssh_data
).private_key(backend=default_backend())
^^^^^^^^^^^^^^^
ValueError: q must be exactly 160, 224, or 256 bits long
[pyinfra_cli.exceptions] File "/usr/lib/python3.13/site-packages/pyinfra_cli/main.py", line 225, in cli
_main(*args, **kwargs)
~~~~~^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/pyinfra_cli/main.py", line 351, in _main
connect_all(state)
~~~~~~~~~~~^^^^^^^
File "/usr/lib/python3.13/site-packages/pyinfra/api/connect.py", line 37, in connect_all
greenlet.get()
~~~~~~~~~~~~^^
File "src/gevent/greenlet.py", line 797, in gevent._gevent_cgreenlet.Greenlet.get
File "src/gevent/greenlet.py", line 373, in gevent._gevent_cgreenlet.Greenlet._raise_exception
File "/usr/lib/python3.13/site-packages/gevent/_compat.py", line 50, in reraise
raise value.with_traceback(tb)
File "src/gevent/greenlet.py", line 900, in gevent._gevent_cgreenlet.Greenlet.run
File "/usr/lib/python3.13/site-packages/pyinfra/api/host.py", line 380, in connect
self.connector.connect()
^^^^^^^
File "/usr/lib/python3.13/site-packages/pyinfra/connectors/ssh.py", line 201, in connect
return self._connect()
^^^
File "/usr/lib/python3.13/site-packages/pyinfra/connectors/ssh.py", line 231, in _connect
self.client.connect(hostname, **kwargs)
^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/pyinfra/connectors/sshuserclient/client.py", line 182, in connect
super().connect(hostname, **config)
^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/paramiko/client.py", line 485, in connect
self._auth(
File "/usr/lib/python3.13/site-packages/paramiko/client.py", line 734, in _auth
self._transport.auth_publickey(username, key)
File "/usr/lib/python3.13/site-packages/paramiko/transport.py", line 1709, in auth_publickey
return self.auth_handler.wait_for_response(my_event)
^^^^^^^^^^^^^^^
File "/usr/lib/python3.13/site-packages/paramiko/auth_handler.py", line 248, in wait_for_response
raise e
File "/usr/lib/python3.13/site-packages/paramiko/transport.py", line 2262, in run
handler(m)
File "/usr/lib/python3.13/site-packages/paramiko/auth_handler.py", line 404, in _parse_service_accept
sig = self.private_key.sign_ssh_data(blob, algorithm)
^^^^^^^
File "/usr/lib/python3.13/site-packages/paramiko/dsskey.py", line 120, in sign_ssh_data
).private_key(backend=default_backend())
^^^^^^^^^^^^^^^
[pyinfra_cli.exceptions] ValueError: q must be exactly 160, 224, or 256 bits long
--> The full traceback has been written to pyinfra-debug.log
--> If this is unexpected please consider submitting a bug report on GitHub, for more information run `pyinfra --support`.
That appears to be a paramiko bug with the handling of key files see: https://github.com/paramiko/paramiko/issues/1839
is there any kind of workaround for this?
ah, it looks like it is trying the first key and if that one fails it gives up. i was able to workaround the issue by reordering my keys in ~/.ssh/config
There seem to be a few different circumstances and approaches to solve this that work for different people when you look at paramikos issue tracker: https://github.com/paramiko/paramiko/issues?q=q%20must%20be%20exactly
congrats on finding a solution so quickly though ;) I simply try to stay away from projects using paramiko for now.