{"record":{"id":"8776215aac04705c","repo":"fatedier/frp","slug":"unknown-public-key-for-remoteaddr-q","errorCode":null,"errorMessage":"unknown public key for remoteAddr %q","messagePattern":"unknown public key for remoteAddr %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/ssh/gateway.go","lineNumber":84,"sourceCode":"\t\treturn nil, err\n\t}\n\tprivateKey, err := ssh.ParsePrivateKey(privateKeyBytes)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tsshConfig.AddHostKey(privateKey)\n\n\tsshConfig.NoClientAuth = cfg.AuthorizedKeysFile == \"\"\n\tsshConfig.PublicKeyCallback = func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {\n\t\tauthorizedKeysMap, err := loadAuthorizedKeysFromFile(cfg.AuthorizedKeysFile)\n\t\tif err != nil {\n\t\t\tlog.Errorf(\"load authorized keys file error: %v\", err)\n\t\t\treturn nil, fmt.Errorf(\"internal error\")\n\t\t}\n\n\t\tuser, ok := authorizedKeysMap[string(key.Marshal())]\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"unknown public key for remoteAddr %q\", conn.RemoteAddr())\n\t\t}\n\t\treturn &ssh.Permissions{\n\t\t\tExtensions: map[string]string{\n\t\t\t\t\"user\": user,\n\t\t\t},\n\t\t}, nil\n\t}\n\n\tln, err := net.Listen(\"tcp\", net.JoinHostPort(bindAddr, strconv.Itoa(cfg.BindPort)))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Gateway{\n\t\tbindPort:           cfg.BindPort,\n\t\tln:                 ln,\n\t\tpeerServerListener: peerServerListener,\n\t\tsshConfig:          sshConfig,\n\t}, nil","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/fatedier/frp/blob/6c8a8d0a97d03b44e9528d30b30c70cb9d61b405/pkg/ssh/gateway.go#L66-L102","documentation":"Returned by the SSH gateway's PublicKeyCallback when the connecting client's public key (compared by marshaled key bytes) is not present in the authorized keys map. This is the SSH equivalent of 'permission denied (publickey)': the key file loaded fine, but the presented key was not listed. The remote address is included to help server operators correlate rejections in logs.","triggerScenarios":"Client runs `ssh -i wrongkey v0@frps-host -p port` where wrongkey's public half is not in AuthorizedKeysFile; or the user regenerated their keypair; or the authorized_keys entry was edited/truncated (key matches by exact marshaled bytes, not by comment or email suffix).","commonSituations":"Using the default SSH key (~/.ssh/id_ed25519) instead of the key registered with the gateway; authorized_keys entry copied with a broken base64 body or missing key-type prefix; multiple team members sharing one gateway file with stale entries.","solutions":["Extract the public key of the key you connect with: ssh-keygen -y -f ~/.ssh/yourkey, and append it as a line to the authorized keys file.","Confirm ssh is actually offering that key: connect with `ssh -v` and look at 'Offering public key' lines.","Check the authorized_keys line is well-formed: <type> <base64> [comment], no line wrapping or trailing whitespace.","Remember the map is keyed on key bytes — identical key material in different files still matches; a different comment on the same key also matches."],"exampleFix":"# generate and register a dedicated key\nssh-keygen -t ed25519 -f ~/.ssh/frp_gateway -N ''\nssh-keygen -y -f ~/.ssh/frp_gateway >> /etc/frp/authorized_keys\n\n# connect\nssh -i ~/.ssh/frp_gateway -p <gatewayPort> v0@<frps-host> \"tcp 127.0.0.1:22\"","handlingStrategy":"validation","validationCode":"# client-side preflight: confirm your key is registered before connecting\nssh-keygen -y -f ~/.ssh/frp_gateway | awk '{print $1\" \"$2}' > /tmp/mypub\nsort /tmp/mypub > /tmp/a; sort /etc/frp/authorized_keys | awk '{print $1\" \"$2}' > /tmp/b\ncmp -s /tmp/a /tmp/b && echo registered || echo \"key NOT in authorized_keys\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register the exact keypair you will connect with; document it per user.","Use `ssh -v` to confirm which key is offered when auth fails.","Keys match by material, not comment — edit the file only by whole lines."],"tags":["ssh","authentication","public-key"],"backgroundTag":null,"analyzedSha":"6c8a8d0a97d03b44e9528d30b30c70cb9d61b405","analyzedAt":"2026-08-15T06:53:27.215Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}