Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bad HTTP response returned from server. Code 400 #720

Open
davidkim2010 opened this issue Jan 2, 2025 · 1 comment
Open

Bad HTTP response returned from server. Code 400 #720

davidkim2010 opened this issue Jan 2, 2025 · 1 comment

Comments

@davidkim2010
Copy link

SUMMARY

Using the following setting, win_group_membership intermittently fails with 'Bad HTTP response returned from server. Code 400" error.

  ansible_connection: winrm
  ansible_port: 5985
  ansible_winrm_transport: ntlm
  ansible_user: Administrator
  ansible_password: '{{ windows.default_admin_password }}'
  ansible_winrm_operation_timeout_sec: 60
  ansible_winrm_read_timeout_sec: 120
- name: Add domain users to Administrators localgroup
  when: AdminUser is defined
  win_group_membership:
    name: Administrators
    members: '{{ AdminUser.split(",") }}'
    state: present
ISSUE TYPE
  • Bug Report
COMPONENT NAME
ANSIBLE VERSION
ansible [core 2.15.8]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/etc/ansible/library']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.9.19 (main, Aug 26 2024, 11:01:47) [GCC 8.5.0 20210514 (Red Hat 8.5.0-22)] (/usr/bin/python3.9)
  jinja version =
COLLECTION VERSION
ansible.windows: 2.5.0
CONFIGURATION
CACHE_PLUGIN(env: ANSIBLE_CACHE_PLUGIN) = jsonfile
CACHE_PLUGIN_CONNECTION(env: ANSIBLE_CACHE_PLUGIN_CONNECTION) = /runner/artifacts/a58baf62-bb1f-40a0-9cd9-a75ea10ce0cb/fact_cache
CALLBACKS_ENABLED(/etc/ansible/ansible.cfg) = ['ansible.posix.profile_tasks', 'community.general.splunk']
CONFIG_FILE() = /etc/ansible/ansible.cfg
DEFAULT_CALLBACK_PLUGIN_PATH(env: ANSIBLE_CALLBACK_PLUGINS) = ['/runner/artifacts/a58baf62-bb1f-40a0-9cd9-a75ea10ce0cb/callback']
DEFAULT_MODULE_PATH(/etc/ansible/ansible.cfg) = ['/etc/ansible/library']
DEFAULT_STDOUT_CALLBACK(env: ANSIBLE_STDOUT_CALLBACK) = awx_display
DEFAULT_TIMEOUT(/etc/ansible/ansible.cfg) = 45
HOST_KEY_CHECKING(env: ANSIBLE_HOST_KEY_CHECKING) = False
RETRY_FILES_ENABLED(env: ANSIBLE_RETRY_FILES_ENABLED) = False
SHOW_CUSTOM_STATS(/etc/ansible/ansible.cfg) = True
OS / ENVIRONMENT

pretty-name: Red Hat Enterprise Linux 8.9 (Ootpa)

STEPS TO REPRODUCE
EXPECTED RESULTS

No error

ACTUAL RESULTS
{
  "msg": "Unexpected failure during module execution: Bad HTTP response returned from server. Code 400",
  "exception": "Traceback (most recent call last):\n  File \"/usr/local/lib/python3.9/site-packages/winrm/protocol.py\", line 268, in send_message\n    root = ET.fromstring(ex.response_text)\n  File \"/usr/lib64/python3.9/xml/etree/ElementTree.py\", line 1348, in XML\n    return parser.close()\nxml.etree.ElementTree.ParseError: no element found: line 1, column 0\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"/usr/lib/python3.9/site-packages/ansible/executor/task_executor.py\", line 165, in run\n    res = self._execute()\n  File \"/usr/lib/python3.9/site-packages/ansible/executor/task_executor.py\", line 660, in _execute\n    result = self._handler.run(task_vars=vars_copy)\n  File \"/usr/lib/python3.9/site-packages/ansible/plugins/action/normal.py\", line 39, in run\n    result = merge_hash(result, self._execute_module(task_vars=task_vars, wrap_async=wrap_async))\n  File \"/usr/lib/python3.9/site-packages/ansible/plugins/action/__init__.py\", line 1179, in _execute_module\n    res = self._low_level_execute_command(cmd, sudoable=sudoable, in_data=in_data)\n  File \"/usr/lib/python3.9/site-packages/ansible/plugins/action/__init__.py\", line 1344, in _low_level_execute_command\n    rc, stdout, stderr = self._connection.exec_command(cmd, in_data=in_data, sudoable=sudoable)\n  File \"/usr/lib/python3.9/site-packages/ansible/plugins/connection/winrm.py\", line 647, in exec_command\n    result = self._winrm_exec(cmd_parts[0], cmd_parts[1:], from_exec=True, stdin_iterator=stdin_iterator)\n  File \"/usr/lib/python3.9/site-packages/ansible/plugins/connection/winrm.py\", line 606, in _winrm_exec\n    self.protocol.cleanup_command(self.shell_id, command_id)\n  File \"/usr/local/lib/python3.9/site-packages/winrm/protocol.py\", line 427, in cleanup_command\n    res = self.send_message(xmltodict.unparse(req))\n  File \"/usr/local/lib/python3.9/site-packages/winrm/protocol.py\", line 271, in send_message\n    raise ex\n  File \"/usr/local/lib/python3.9/site-packages/winrm/protocol.py\", line 263, in send_message\n    resp = self.transport.send_message(message)\n  File \"/usr/local/lib/python3.9/site-packages/winrm/transport.py\", line 336, in send_message\n    response = self._send_message_request(session, prepared_request)\n  File \"/usr/local/lib/python3.9/site-packages/winrm/transport.py\", line 352, in _send_message_request\n    raise WinRMTransportError(\"http\", ex.response.status_code, response_text.decode())\nwinrm.exceptions.WinRMTransportError: Bad HTTP response returned from server. Code 400\n",
  "stdout": "",
  "_ansible_no_log": false
}

@jborean93
Copy link
Collaborator

jborean93 commented Jan 7, 2025

There is unfortunately not much information provided by WSMan to indicate why the 400 error code was returned by the WSMan service. Just for easier visibility in the future the exception traceback in an easier to read format is

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/winrm/protocol.py", line 268, in send_message
    root = ET.fromstring(ex.response_text)
  File "/usr/lib64/python3.9/xml/etree/ElementTree.py", line 1348, in XML
    return parser.close()
xml.etree.ElementTree.ParseError: no element found: line 1, column 0

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.9/site-packages/ansible/executor/task_executor.py", line 165, in run
    res = self._execute()
  File "/usr/lib/python3.9/site-packages/ansible/executor/task_executor.py", line 660, in _execute
    result = self._handler.run(task_vars=vars_copy)
  File "/usr/lib/python3.9/site-packages/ansible/plugins/action/normal.py", line 39, in run
    result = merge_hash(result, self._execute_module(task_vars=task_vars, wrap_async=wrap_async))
  File "/usr/lib/python3.9/site-packages/ansible/plugins/action/__init__.py", line 1179, in _execute_module
    res = self._low_level_execute_command(cmd, sudoable=sudoable, in_data=in_data)
  File "/usr/lib/python3.9/site-packages/ansible/plugins/action/__init__.py", line 1344, in _low_level_execute_command
    rc, stdout, stderr = self._connection.exec_command(cmd, in_data=in_data, sudoable=sudoable)
  File "/usr/lib/python3.9/site-packages/ansible/plugins/connection/winrm.py", line 647, in exec_command
    result = self._winrm_exec(cmd_parts[0], cmd_parts[1:], from_exec=True, stdin_iterator=stdin_iterator)
  File "/usr/lib/python3.9/site-packages/ansible/plugins/connection/winrm.py", line 606, in _winrm_exec
    self.protocol.cleanup_command(self.shell_id, command_id)
  File "/usr/local/lib/python3.9/site-packages/winrm/protocol.py", line 427, in cleanup_command
    res = self.send_message(xmltodict.unparse(req))
  File "/usr/local/lib/python3.9/site-packages/winrm/protocol.py", line 271, in send_message
    raise ex
  File "/usr/local/lib/python3.9/site-packages/winrm/protocol.py", line 263, in send_message
    resp = self.transport.send_message(message)
  File "/usr/local/lib/python3.9/site-packages/winrm/transport.py", line 336, in send_message
    response = self._send_message_request(session, prepared_request)
  File "/usr/local/lib/python3.9/site-packages/winrm/transport.py", line 352, in _send_message_request
    raise WinRMTransportError("http", ex.response.status_code, response_text.decode())
winrm.exceptions.WinRMTransportError: Bad HTTP response returned from server. Code 400

It is curious if this is happening at self.protocol.cleanup_command(self.shell_id, command_id). It makes me wonder if there's some sort of funky state or race condition on the server where it's unable to detect the command id to cleanup. Is it possible for you to temporarily change the following lines at /usr/lib/python3.9/site-packages/ansible/plugins/connection/winrm.py.

https://github.com/ansible/ansible/blob/ba1854271b3a6a20d2d9edd25d78c46a7413e604/lib/ansible/plugins/connection/winrm.py#L604-L606

to

        finally:
            if command_id:
                try:
                    self.protocol.cleanup_command(self.shell_id, command_id)
                except Exception as e:
                    display.warning(f"Failure when cleaning up the WinRM command - attempting to continue: {type(e).__name__} {e}")

This may not be possible if you don't have permission, an alternative option is run from a virtual environment where you have full control over the install files and can easily blow away the changes once done testing.

An alternative is to look at using the psrp connection plugin. This plugin also uses WSMan as the underlying connection but on a different type of remote shell that is less susceptible to race conditions and problems stemming from the host being under load that winrm can be problematic with.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants