{"record":{"id":"013279a0473ae015","repo":"gitlabhq/gitlabhq","slug":"invalid-ssh-host-key-s-invalid-keys-join","errorCode":null,"errorMessage":"Invalid SSH host key(s): #{invalid_keys.join(', ')}","messagePattern":"Invalid SSH host key\\(s\\): #(.+?)","errorType":"exception","errorClass":"RemoteMirrors::HostKeysConverter::InvalidHostKeyError","httpStatus":400,"severity":"error","filePath":"app/models/remote_mirrors/host_keys_converter.rb","lineNumber":76,"sourceCode":"      end\n\n      normalized_keys.join(\"\\n\").presence\n    end\n\n    private\n\n    attr_reader :host_keys, :url\n\n    def validate!\n      raise InvalidHostKeyError, [\"too many host keys (maximum is #{MAX_HOST_KEYS})\"] if host_keys.size > MAX_HOST_KEYS\n\n      invalid = sanitized_keys.filter_map do |key|\n        next if key.blank?\n\n        key unless Gitlab::SSHPublicKey.new(key).valid?\n      end\n\n      raise InvalidHostKeyError, invalid if invalid.present?\n    end\n\n    def sanitized_keys\n      @sanitized_keys ||= host_keys.map do |key|\n        sanitize_key(key.to_s.strip)\n      end\n    end\n\n    def sanitize_key(key)\n      parts = Gitlab::SSHPublicKey.extract_key_parts(key)\n      return key unless parts\n\n      [parts[:prefix].presence, parts[:algorithm], restore_base64_encoding(parts[:key_data])].compact.join(' ')\n    end\n\n    # Form-encoded params (application/x-www-form-urlencoded) decode '+' as spaces.\n    # SSH key base64 data uses '+' characters, so we restore them here.\n    def restore_base64_encoding(key_data)","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/gitlabhq/gitlabhq/blob/55ee20384a1f55cb0e362dee1d07149613b1b9bf/app/models/remote_mirrors/host_keys_converter.rb#L58-L94","documentation":"Error \"Invalid SSH host key(s): #{invalid_keys.join(', ')}\" thrown in gitlabhq/gitlabhq.","triggerScenarios":"Thrown at app/models/remote_mirrors/host_keys_converter.rb:76 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"55ee20384a1f55cb0e362dee1d07149613b1b9bf","analyzedAt":"2026-08-21T14:22:27.782Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}