How to debug "pika.exceptions.AuthenticationError: EXTERNAL" error when establishing TLS connection to RabbitMQ?
Question: I have a RabbitMQ 3.6.1 server on Ubuntu 14.04 running properly. I tried to
configure an SSL listener according to [official
documentation](https://www.rabbitmq.com/ssl.html). No problems during the
startup.

However when trying to establish a connection, I get the following error on
Python/pika side (full transcript below):

    
    
    pika.exceptions.AuthenticationError: EXTERNAL
    

What does `EXTERNAL` mean here? How to debug / get further details of the
error?

* * *

Course of actions (to test I used a Vagrant box and a local connection):

  1. RabbitMQ starts SSL Listener on port 5671 (per `/var/log/rabbitmq/rabbit@rabbitmq-server.log`):
    
        started SSL Listener on [::]:5671
    

  2. I execute the `pika.BlockingConnection` on the client side.

  3. On the server side I can see an incoming connection:
    
        =INFO REPORT==== 17-Apr-2016::17:07:15 ===
    accepting AMQP connection <0.2788.0> (127.0.0.1:48404 -> 127.0.0.1:5671)
    

  4. Client fails with:
    
        pika.exceptions.AuthenticationError: EXTERNAL
    

  5. Server timeouts:
    
        =ERROR REPORT==== 17-Apr-2016::17:07:25 ===
    closing AMQP connection <0.2788.0> (127.0.0.1:48404 -> 127.0.0.1:5671):
    {handshake_timeout,frame_header}
    

* * *

Full transcript of the client side:

    
    
    >>> import pika, ssl
    >>> from pika.credentials import ExternalCredentials
    >>> ssl_options = ({"ca_certs": "/etc/rabbitmq/certs/testca/cacert.pem",
    ...                 "certfile": "/etc/rabbitmq/certs/client/cert.pem",
    ...                 "keyfile": "/etc/rabbitmq/certs/client/key.pem",
    ...                 "cert_reqs": ssl.CERT_REQUIRED,
    ...                 "server_side": False})
    >>> host = "localhost"
    >>> connection = pika.BlockingConnection(
    ...                  pika.ConnectionParameters(
    ...                      host, 5671, credentials=ExternalCredentials(),
    ...                      ssl=True, ssl_options=ssl_options))
    Traceback (most recent call last):
      File "<stdin>", line 4, in <module>
      File "/usr/local/lib/python2.7/dist-packages/pika/adapters/blocking_connection.py", line 339, in __init__
        self._process_io_for_connection_setup()
      File "/usr/local/lib/python2.7/dist-packages/pika/adapters/blocking_connection.py", line 374, in _process_io_for_connection_setup
        self._open_error_result.is_ready)
      File "/usr/local/lib/python2.7/dist-packages/pika/adapters/blocking_connection.py", line 410, in _flush_output
        self._impl.ioloop.poll()
      File "/usr/local/lib/python2.7/dist-packages/pika/adapters/select_connection.py", line 602, in poll
        self._process_fd_events(fd_event_map, write_only)
      File "/usr/local/lib/python2.7/dist-packages/pika/adapters/select_connection.py", line 443, in _process_fd_events
        handler(fileno, events, write_only=write_only)
      File "/usr/local/lib/python2.7/dist-packages/pika/adapters/base_connection.py", line 364, in _handle_events
        self._handle_read()
      File "/usr/local/lib/python2.7/dist-packages/pika/adapters/base_connection.py", line 415, in _handle_read
        self._on_data_available(data)
      File "/usr/local/lib/python2.7/dist-packages/pika/connection.py", line 1347, in _on_data_available
        self._process_frame(frame_value)
      File "/usr/local/lib/python2.7/dist-packages/pika/connection.py", line 1414, in _process_frame
        if self._process_callbacks(frame_value):
      File "/usr/local/lib/python2.7/dist-packages/pika/connection.py", line 1384, in _process_callbacks
        frame_value)  # Args
      File "/usr/local/lib/python2.7/dist-packages/pika/callback.py", line 60, in wrapper
        return function(*tuple(args), **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/pika/callback.py", line 92, in wrapper
        return function(*args, **kwargs)
      File "/usr/local/lib/python2.7/dist-packages/pika/callback.py", line 236, in process
        callback(*args, **keywords)
      File "/usr/local/lib/python2.7/dist-packages/pika/connection.py", line 1298, in _on_connection_start
        self._send_connection_start_ok(*self._get_credentials(method_frame))
      File "/usr/local/lib/python2.7/dist-packages/pika/connection.py", line 1077, in _get_credentials
        raise exceptions.AuthenticationError(self.params.credentials.TYPE)
    pika.exceptions.AuthenticationError: EXTERNAL
    >>>
    


Answer: The Python / pika code in the question is correct.

The error:

> pika.exceptions.AuthenticationError: EXTERNAL

is reported when client certificate authorisation is not enabled on the
RabbitMQ server side. The word `EXTERNAL` in the error refers to the
authentication mechanism as [described
here](https://github.com/rabbitmq/rabbitmq-auth-mechanism-
ssl/blob/rabbitmq_v3_6_1/README.md).

To enable:

    
    
    rabbitmq-plugins enable rabbitmq_auth_mechanism_ssl
    

