{"record":{"id":"1a8032033541bb44","repo":"wavetermdev/waveterm","slug":"bad-response-from-server-questions-has-len-d-ec","errorCode":null,"errorMessage":"bad response from server: questions has len %d, echos has len %d","messagePattern":"bad response from server: questions has len (.+?), echos has len (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/remote/sshclient.go","lineNumber":431,"sourceCode":"\t\tif err != nil {\n\t\t\tblocklogger.Infof(connCtx, \"[conndebug] ERROR Password Authentication failed: %v\\n\", SimpleMessageFromPossibleConnectionError(err))\n\t\t\treturn \"\", ConnectionError{ConnectionDebugInfo: debugInfo, Err: err}\n\t\t}\n\t\tblocklogger.Infof(connCtx, \"[conndebug] got password from user, sending to ssh\\n\")\n\t\treturn response.Text, nil\n\t}\n}\n\nfunc createInteractiveKbdInteractiveChallenge(connCtx context.Context, remoteName string, debugInfo *ConnectionDebugInfo) func(name, instruction string, questions []string, echos []bool) (answers []string, err error) {\n\treturn func(name, instruction string, questions []string, echos []bool) (answers []string, outErr error) {\n\t\tdefer func() {\n\t\t\tpanicErr := panichandler.PanicHandler(\"sshclient:kbdinteractive-callback\", recover())\n\t\t\tif panicErr != nil {\n\t\t\t\toutErr = panicErr\n\t\t\t}\n\t\t}()\n\t\tif len(questions) != len(echos) {\n\t\t\treturn nil, fmt.Errorf(\"bad response from server: questions has len %d, echos has len %d\", len(questions), len(echos))\n\t\t}\n\t\tfor i, question := range questions {\n\t\t\techo := echos[i]\n\t\t\tanswer, err := promptChallengeQuestion(connCtx, question, echo, remoteName)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, ConnectionError{ConnectionDebugInfo: debugInfo, Err: utilds.MakeCodedError(ConnErrCode_UserCancelled, err)}\n\t\t\t}\n\t\t\tanswers = append(answers, answer)\n\t\t}\n\t\treturn answers, nil\n\t}\n}\n\nfunc promptChallengeQuestion(connCtx context.Context, question string, echo bool, remoteName string) (answer string, err error) {\n\t// limited to 15 seconds for some reason. this should be investigated more\n\t// in the future\n\tctx, cancelFn := context.WithTimeout(connCtx, 60*time.Second)\n\tdefer cancelFn()","sourceCodeStart":413,"sourceCodeEnd":449,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/remote/sshclient.go#L413-L449","documentation":"The keyboard-interactive auth callback validates that the server sent equal-length 'questions' and 'echos' arrays before prompting the user. A mismatch means the server produced a malformed keyboard-interactive challenge, so the client cannot map answers back to prompts and aborts with this error. It protects against misbehaving or non-standard SSH servers.","triggerScenarios":"Connecting to an SSH server (or intermediate gateway/MFA device) whose keyboard-interactive implementation returns challenges where len(questions) != len(echos), e.g. a buggy PAM stack or custom SSH server.","commonSituations":"Connecting through VPN/MFA gateways, multi-factor PAM modules, or non-OpenSSH servers (some appliances, older firmware) that emit inconsistent kbd-interactive packets.","solutions":["Update the SSH server / appliance firmware to a version with correct keyboard-interactive support.","Disable keyboard-interactive auth on the server (PasswordAuthentication or pubkey-only) so a compliant method is used.","Connect directly to the host if the malformed challenge comes from an intermediate jump/bastion device.","If you control the PAM config, fix or replace the MFA module returning mismatched prompts."],"exampleFix":"// before (sshd_config on server)\nKbdInteractiveAuthentication yes\n// after\nKbdInteractiveAuthentication no  # or fix the PAM module emitting mismatched prompts","handlingStrategy":"retry","validationCode":"// probe the server before connecting\nconn, err := ssh.Dial(\"tcp\", host, ssh.ClientConfig{...})\n// if you get this error deterministically, the server's kbd-interactive is broken","typeGuard":null,"tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"bad response from server\") {\n        // retry with a ClientConfig that disables KeyboardInteractiveChallenge,\n        // relying on password/publickey auth\n    }\n}","preventionTips":["Test connectivity with OpenSSH's ssh client first; if it also fails, the server is at fault.","Keep SSH server/appliance firmware updated.","Prefer publickey auth on servers with non-standard PAM/MFA stacks.","Disable kbd-interactive on the server if it emits mismatched prompts."],"tags":["ssh","keyboard-interactive","protocol"],"backgroundTag":"ssh-server-malformed-challenge","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}