kovidgoyal/kitty · error

KITTY_PUBLIC_KEY environment variable does not have a : in i

Error message

KITTY_PUBLIC_KEY environment variable does not have a : in it

What it means

KITTY_PUBLIC_KEY was found but is malformed: it must be of the form '<version>:<base85 key>' and contains no ':'. kitty @ cannot parse the encryption public key needed to password-protect remote control commands.

Source

Thrown at tools/cmd/at/main.go:83

func set_payload_string_field(io_data *rc_io_data, field, data string) {
	payload_interface := reflect.ValueOf(&io_data.rc.Payload).Elem()
	struct_in_interface := reflect.New(payload_interface.Elem().Type()).Elem()
	struct_in_interface.Set(payload_interface.Elem()) // copies the payload to struct_in_interface
	struct_in_interface.FieldByName(field).SetString(data)
	payload_interface.Set(struct_in_interface) // copies struct_in_interface back to payload
}

func get_pubkey(encoded_key string) (encryption_version string, pubkey []byte, err error) {
	if encoded_key == "" {
		encoded_key = os.Getenv("KITTY_PUBLIC_KEY")
		if encoded_key == "" {
			err = fmt.Errorf("Password usage requested but KITTY_PUBLIC_KEY environment variable is not available")
			return
		}
	}
	encryption_version, encoded_key, found := strings.Cut(encoded_key, ":")
	if !found {
		err = fmt.Errorf("KITTY_PUBLIC_KEY environment variable does not have a : in it")
		return
	}
	if encryption_version != kitty.RC_ENCRYPTION_PROTOCOL_VERSION {
		err = fmt.Errorf("KITTY_PUBLIC_KEY has unknown version, if you are running on a remote system, update kitty on this system")
		return
	}
	pubkey = make([]byte, base85.DecodedLen(len(encoded_key)))
	n, err := base85.Decode(pubkey, []byte(encoded_key))
	if err == nil {
		pubkey = pubkey[:n]
	}
	return
}

type escaped_string string

func (s escaped_string) MarshalJSON() ([]byte, error) {
	// See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON

View on GitHub (pinned to 6d5d0c4406)

Solutions

  1. Unset the broken value and let kitty export the real variable: unset KITTY_PUBLIC_KEY, then run inside kitty
  2. When forwarding manually, copy the entire '1:KEY...' string verbatim including the version prefix
  3. Check shell quoting when exporting (avoid word-splitting or history expansion mangling it)
Defensive patterns

Strategy: validation

Validate before calling

v := os.Getenv("KITTY_PUBLIC_KEY")
if _, _, ok := strings.Cut(v, ":"); !ok { /* bad env value; unset and re-export */ }

Type guard

func wellFormedPubKey(v string) bool { _, _, ok := strings.Cut(v, ":"); return ok }

Prevention

When it happens

Trigger: get_pubkey does strings.Cut(encoded_key, ":"); any manually set or mangled KITTY_PUBLIC_KEY lacking a colon (someone exported a bare key or truncated the value) triggers this.

Common situations: Users manually copying only part of the variable when forwarding it over ssh, shell quoting/escaping mistakes that strip the version prefix, or a stale/foreign value left in the environment.

Related errors


AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27). Data as JSON: /api/errors/f3bbdb01064d86d0. Report an issue: GitHub.