kovidgoyal/kitty · error · ValueError
Incorrect permissions on pwfile: 0o{mode:03o}
Error message
Incorrect permissions on pwfile: 0o{mode:03o} What it means
read_data_from_shared_memory() requires the ssh kitten's password shm file to have exactly mode 0600 (S_IREAD | S_IWRITE, i.e. owner-only read/write). stat.S_IMODE(shm.stats.st_mode) is compared to 0o600 and any other permission bits raise ValueError('Incorrect permissions on pwfile: 0o...'). This prevents other users on the machine reading the transmitted password.
Source
Thrown at kittens/ssh/utils.py:172
shm.flush()
atexit.register(shm.close) # keeps shm alive till exit
get_boss().atexit.shm_unlink(shm.name)
return shm.name
def read_data_from_shared_memory(shm_name: str) -> Any:
import json
import stat
from kitty.shm import SharedMemory
with SharedMemory(shm_name, readonly=True) as shm:
shm.unlink()
if shm.stats.st_uid != os.geteuid() or shm.stats.st_gid != os.getegid():
raise ValueError(f'Incorrect owner on pwfile: uid={shm.stats.st_uid} gid={shm.stats.st_gid}')
mode = stat.S_IMODE(shm.stats.st_mode)
if mode != stat.S_IREAD | stat.S_IWRITE:
raise ValueError(f'Incorrect permissions on pwfile: 0o{mode:03o}')
return json.loads(shm.read_data_with_size())
def get_ssh_data(msgb: memoryview, request_id: str) -> Iterator[bytes | memoryview]:
# Unfortunately we cannot use EOF (\x04) to flush the kernel line buffer
# because ssh with controlmasters mangles EOF replacing it with null bytes
from base64 import standard_b64decode
yield b'\nKITTY_DATA_START\n' # to discard leading data
try:
msg = standard_b64decode(msgb).decode('utf-8')
md = dict(x.split('=', 1) for x in msg.split(':'))
pw = md['pw']
pwfilename = md['pwfile']
rq_id = md['id']
except Exception:
traceback.print_exc()
yield b'invalid ssh data request message\n'View on GitHub (pinned to 6d5d0c4406)
Solutions
- Remove the offending file (`rm /dev/shm/kitty-ssh-*` style names) so kitty recreates it with mode 0600, then retry.
- Check your umask; start kitty with a normal umask (0022) so the shm file is created 0600.
- Do not chmod or copy pwfiles in /dev/shm; if you backed them up for debugging, delete them.
- If it persists, verify no other process is creating the file and report/check the kitty version for shm creation regressions.
Example fix
# before ls -l /dev/shm/kitty* # -rw-r--r-- -> ValueError: Incorrect permissions on pwfile: 0o644 # after rm /dev/shm/kitty* kitten ssh host # file recreated with 0600
Defensive patterns
Strategy: validation
Validate before calling
import os, stat, glob
def clean_bad_mode_shm() -> None:
for p in glob.glob('/dev/shm/kitty*'):
try:
mode = stat.S_IMODE(os.stat(p).st_mode)
if mode != 0o600:
os.unlink(p)
except FileNotFoundError:
pass Try / catch
try:
data = read_data_from_shared_memory(name)
except ValueError as e:
if 'Incorrect permissions on pwfile' in str(e):
remove_stale_pwfile(); retry_once() # kitty recreates with 0600
else:
raise Prevention
- Never chmod or manually create files kitty will use in /dev/shm.
- Start kitty with a standard umask (0022).
- After restoring backups or debugging /dev/shm, delete copied kitty pwfiles.
When it happens
Trigger: get_ssh_data() reads a pwfile in /dev/shm whose mode is not 0600 — e.g. created with a permissive umask, chmod'ed to 0644/0666 afterwards, restored from a backup with wrong modes, or written by a non-kitty process that uses default shm creation modes.
Common situations: A restrictive/permissive umask in the shell that launched kitty; another tool or script pre-creating or copying the shm file with different permissions; hardened or custom tmpfs mount options; debugging sessions where the file was touched manually.
Related errors
- Incorrect owner on pwfile: uid={shm.stats.st_uid} gid={shm.s
- Incorrect password
- This should be run as kitten ssh
- Incorrect request id: {rq_id!r} expecting the KITTY_PID-KITT
- unknown option -- {arg[1:]}
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/5add1c6f3ce6d7ff.
Report an issue: GitHub.