python/cpython · error · TypeError
data: expecting a bytes-like instance, got {type(data).__nam
Error message
data: expecting a bytes-like instance, got {type(data).__name__} What it means
Raised by _SSLProtocolTransport.write() in asyncio.sslproto as TypeError when data is not bytes, bytearray, or memoryview. This is the TLS transport's equivalent of the plain-socket transport check: the SSL protocol layer feeds raw bytes into the OpenSSL BIO, so str or other types cannot be accepted.
Source
Thrown at Lib/asyncio/sslproto.py:218
self._ssl_protocol._incoming_high_water)
def get_read_buffer_size(self):
"""Return the current size of the read buffer."""
return self._ssl_protocol._get_read_buffer_size()
@property
def _protocol_paused(self):
# Required for sendfile fallback pause_writing/resume_writing logic
return self._ssl_protocol._app_writing_paused
def write(self, data):
"""Write some data bytes to the transport.
This does not block; it buffers the data and arranges for it
to be sent out asynchronously.
"""
if not isinstance(data, (bytes, bytearray, memoryview)):
raise TypeError(f"data: expecting a bytes-like instance, "
f"got {type(data).__name__}")
if not data:
return
self._ssl_protocol._write_appdata((data,))
def writelines(self, list_of_data):
"""Write a list (or any iterable) of data bytes to the transport.
The default implementation concatenates the arguments and
calls write() on the result.
"""
self._ssl_protocol._write_appdata(list_of_data)
def write_eof(self):
"""Close the write end after flushing buffered data.
This raises :exc:`NotImplementedError` right now.
"""View on GitHub (pinned to bc6749cc3b)
Solutions
- Encode string payloads: transport.write(text.encode('utf-8')).
- Type-check at your protocol boundary: assert isinstance(data, (bytes, bytearray, memoryview)).
- Convert structured data explicitly: transport.write(json.dumps(obj).encode()) or struct.pack formats.
Example fix
// before
writer.write("GET / HTTP/1.1\r\nHost: x\r\n\r\n") # str over TLS -> TypeError
// after
writer.write(b"GET / HTTP/1.1\r\nHost: x\r\n\r\n") Defensive patterns
Strategy: type-guard
Validate before calling
def tls_write(transport, data):
if isinstance(data, str):
data = data.encode('utf-8')
elif not isinstance(data, (bytes, bytearray, memoryview)):
raise TypeError(f'cannot send {type(data).__name__} over TLS transport')
transport.write(data) Type guard
BytesLike = (bytes, bytearray, memoryview)
def is_bytes_like(data) -> bool:
return isinstance(data, BytesLike) Try / catch
try:
transport.write(data)
except TypeError as e:
if 'bytes-like instance' in str(e):
transport.write(data.encode('utf-8') if isinstance(data, str) else bytes(data))
else:
raise Prevention
- Use bytes literals (b'...') in protocol code paths that run under TLS.
- Encode once at the edge; keep internal message types bytes.
- Run protocol tests with ssl=ctx against a loopback TLS server to catch str leaks.
When it happens
Trigger: Calling write() on the transport obtained from an SSL connection (loop.create_connection with ssl=ctx, await asyncio.open_connection(..., ssl=ctx), or start_tls upgrades) with a str or non-bytes object; usually via StreamWriter.write forwarding.
Common situations: Code that worked against a plain-socket mock or third-party transport accepting str breaks when TLS is enabled and the real _SSLProtocolTransport is used; forgetting .encode() on JSON/string payloads in HTTPS client scripts.
Related errors
- Socket cannot be of type SSLSocket
- server_hostname is only meaningful with ssl
- You must set server_hostname when using ssl without a host
- ssl_handshake_timeout is only meaningful with ssl
- ssl_shutdown_timeout is only meaningful with ssl
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/ecd2c29e562413e8.
Report an issue: GitHub.