{"record":{"id":"b3160d22b3fc99dd","repo":"kovidgoyal/kitty","slug":"kitty-public-key-env-var-not-set-cannot-transmit","errorCode":null,"errorMessage":"KITTY_PUBLIC_KEY env var not set, cannot transmit password securely","messagePattern":"KITTY_PUBLIC_KEY env var not set, cannot transmit password securely","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kittens/transfer/utils.go","lineNumber":50,"sourceCode":"\t\treturn utils.Expanduser(\"~\")\n\t}\n\treturn global_home\n}\n\nfunc encode_bypass(request_id string, bypass string) (string, error) {\n\tq := request_id + \";\" + bypass\n\tif pkey_encoded := os.Getenv(\"KITTY_PUBLIC_KEY\"); pkey_encoded != \"\" {\n\t\tencryption_protocol, pubkey, err := crypto.DecodePublicKey(pkey_encoded)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\tencrypted, err := crypto.Encrypt_data(utils.UnsafeStringToBytes(q), pubkey, encryption_protocol)\n\t\tif err != nil {\n\t\t\treturn \"\", err\n\t\t}\n\t\treturn fmt.Sprintf(\"kitty-1:%s\", utils.UnsafeBytesToString(encrypted)), nil\n\t}\n\treturn \"\", fmt.Errorf(\"KITTY_PUBLIC_KEY env var not set, cannot transmit password securely\")\n}\n\nfunc abspath(path string, use_home ...bool) string {\n\tif filepath.IsAbs(path) {\n\t\treturn path\n\t}\n\tvar base string\n\tif len(use_home) > 0 && use_home[0] {\n\t\tbase = home_path()\n\t} else {\n\t\tbase = cwd_path()\n\t}\n\treturn filepath.Join(base, path)\n}\n\nfunc expand_home(path string) string {\n\tif strings.HasPrefix(path, \"~\"+string(os.PathSeparator)) {\n\t\tpath = strings.TrimLeft(path[2:], string(os.PathSeparator))","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kittens/transfer/utils.go#L32-L68","documentation":"The transfer kitten encrypts the password/file data with the recipient's public key before sending it over the socket. It reads the recipient's base64 public key from the KITTY_PUBLIC_KEY environment variable; when that variable is empty or unset, encryption cannot be performed and encode_bypass returns this error instead of transmitting the secret in plaintext.","triggerScenarios":"Calling kittens/transfer code paths that send a password or encrypted payload (receive_loop, initialize) in a process where KITTY_PUBLIC_KEY is not in the environment — e.g. running the transfer kitten manually, spawning it through a wrapper that strips env vars, or a kitten version mismatch where the parent never exported the key.","commonSituations":"Running the transfer kitten outside a normal kitty window session; SSH/tmux environments that drop kitty-specific env vars; stale kitty versions where the remote side doesn't advertise its public key; scripts invoking the kitten binary directly for testing.","solutions":["Ensure the transfer kitten is launched from within kitty itself, which sets KITTY_PUBLIC_KEY on the child process","Upgrade both ends (sender and receiver) to matching kitty versions so public key exchange happens","If invoking manually, export a valid base64 public key: KITTY_PUBLIC_KEY=$(kitty +kitten query-public-key) before running the kitten","Avoid sending passwords when the key is unavailable: pass an empty password and authenticate out-of-band"],"exampleFix":"// before\nq := os.Getenv(\"KITTY_PUBLIC_KEY\")\nencrypted, err := crypto.Encrypt_data([]byte(pw), pubkey, proto)\n\n// after\npubkey := os.Getenv(\"KITTY_PUBLIC_KEY\")\nif pubkey == \"\" {\n    log.Fatal(\"run this kitten from inside kitty so KITTY_PUBLIC_KEY is set\")\n}","handlingStrategy":"validation","validationCode":"pubkey := os.Getenv(\"KITTY_PUBLIC_KEY\")\nif pubkey == \"\" {\n    return errors.New(\"KITTY_PUBLIC_KEY missing; run inside kitty or export the recipient public key\")\n}","typeGuard":null,"tryCatchPattern":"if _, err := encode_bypass(pw); err != nil {\n    if strings.Contains(err.Error(), \"KITTY_PUBLIC_KEY\") {\n        // fall back to manual password entry / abort transfer\n    }\n}","preventionTips":["Launch transfer kittens from within kitty so env vars are inherited","Validate required env vars at process start, not at send time","Keep kitty versions matched on both ends of the transfer"],"tags":["kitty","transfer","encryption","env-var","public-key"],"backgroundTag":"missing-env-var","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}