I have a Django application that has been deployed to a customer for about a year. The application is deployed with an Apache web server. They recently asked for a simple chat window to be added. I have implemented this with channels and Daphne. It works just fine in my development environment (i.e. python manage.py runserver) using both the in memory and redis back ends. Now I’m trying to get it to work in a production environment. I am still using Apache with it forwarding web socket to Daphne. As far as I can tell I also need to install the redis-server. I have done this and have it configured to run under systemd. I have the chat window working as expected using the in memory back end and am now trying to get it to work using the redis back end. Unfortunately I get this error from the Daphne service (i.e. journalctl -xeu daphne.service).
Mar 25 15:43:35 Stout daphne[1877778]: ChatConsumer:connect channel: specific.1c104be543f142c7a794544f1a401a72!2ed22171937340609b8a4c49e9fe8462
Mar 25 15:43:35 Stout daphne[1877778]: ChatConsumer:connect, add group: chat to channel specific.1c104be543f142c7a794544f1a401a72!2ed22171937340609b8a4c49e9fe8462
Mar 25 15:43:36 Stout daphne[1877778]: 2026-03-25 15:43:36,438 ERROR Exception inside application: label empty or too long
Mar 25 15:43:36 Stout daphne[1877778]: Traceback (most recent call last):
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/redis/asyncio/connection.py”, line 307, in connect_check_health
Mar 25 15:43:36 Stout daphne[1877778]: await self.retry.call_with_retry(
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/redis/asyncio/retry.py”, line 50, in call_with_retry
Mar 25 15:43:36 Stout daphne[1877778]: return await do()
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/redis/asyncio/connection.py”, line 768, in _connect
Mar 25 15:43:36 Stout daphne[1877778]: reader, writer = await asyncio.open_connection(
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/usr/lib/python3.12/asyncio/streams.py”, line 48, in open_connection
Mar 25 15:43:36 Stout daphne[1877778]: transport, _ = await loop.create_connection(
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/usr/lib/python3.12/asyncio/base_events.py”, line 1080, in create_connection
Mar 25 15:43:36 Stout daphne[1877778]: infos = await self._ensure_resolved(
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/usr/lib/python3.12/asyncio/base_events.py”, line 1456, in _ensure_resolved
Mar 25 15:43:36 Stout daphne[1877778]: return await loop.getaddrinfo(host, port, family=family, type=type,
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/usr/lib/python3.12/asyncio/base_events.py”, line 901, in getaddrinfo
Mar 25 15:43:36 Stout daphne[1877778]: return await self.run_in_executor(
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/usr/lib/python3.12/concurrent/futures/thread.py”, line 58, in run
Mar 25 15:43:36 Stout daphne[1877778]: result = self.fn(*self.args, **self.kwargs)
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/usr/lib/python3.12/socket.py”, line 963, in getaddrinfo
Mar 25 15:43:36 Stout daphne[1877778]: for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/usr/lib/python3.12/encodings/idna.py”, line 173, in encode
Mar 25 15:43:36 Stout daphne[1877778]: raise UnicodeError(“label empty or too long”)
Mar 25 15:43:36 Stout daphne[1877778]: UnicodeError: label empty or too long
Mar 25 15:43:36 Stout daphne[1877778]: encoding with ‘idna’ codec failed
Mar 25 15:43:36 Stout daphne[1877778]: The above exception was the direct cause of the following exception:
Mar 25 15:43:36 Stout daphne[1877778]: Traceback (most recent call last):
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/channels/routing.py”, line 48, in call
Mar 25 15:43:36 Stout daphne[1877778]: return await application(scope, receive, send)
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/channels/sessions.py”, line 44, in call
Mar 25 15:43:36 Stout daphne[1877778]: return await self.inner(dict(scope, cookies=cookies), receive, send)
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/channels/sessions.py”, line 261, in call
Mar 25 15:43:36 Stout daphne[1877778]: return await self.inner(wrapper.scope, receive, wrapper.send)
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/channels/auth.py”, line 185, in call
Mar 25 15:43:36 Stout daphne[1877778]: return await super().call(scope, receive, send)
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/channels/middleware.py”, line 24, in call
Mar 25 15:43:36 Stout daphne[1877778]: return await self.inner(scope, receive, send)
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/channels/routing.py”, line 118, in call
Mar 25 15:43:36 Stout daphne[1877778]: return await application(
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/channels/consumer.py”, line 95, in app
Mar 25 15:43:36 Stout daphne[1877778]: return await consumer(scope, receive, send)
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/channels/consumer.py”, line 58, in call
Mar 25 15:43:36 Stout daphne[1877778]: await await_many_dispatch(
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/channels/utils.py”, line 50, in await_many_dispatch
Mar 25 15:43:36 Stout daphne[1877778]: await dispatch(result)
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/channels/consumer.py”, line 74, in dispatch
Mar 25 15:43:36 Stout daphne[1877778]: await handler(message)
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/channels/generic/websocket.py”, line 180, in websocket_connect
Mar 25 15:43:36 Stout daphne[1877778]: await self.connect()
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/CSRMedical/medical/patients/consumers.py”, line 15, in connect
Mar 25 15:43:36 Stout daphne[1877778]: await self.channel_layer.group_add(
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/channels_redis/core.py”, line 493, in group_add
Mar 25 15:43:36 Stout daphne[1877778]: await connection.zadd(group_key, {channel: time.time()})
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/redis/asyncio/client.py”, line 720, in execute_command
Mar 25 15:43:36 Stout daphne[1877778]: conn = self.connection or await pool.get_connection()
Mar 25 15:43:36 Stout daphne[1877778]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/redis/asyncio/connection.py”, line 1198, in get_connection
Mar 25 15:43:36 Stout daphne[1877778]: await self.ensure_connection(connection)
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/redis/asyncio/connection.py”, line 1231, in ensure_connection
Mar 25 15:43:36 Stout daphne[1877778]: await connection.connect()
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/redis/asyncio/connection.py”, line 298, in connect
Mar 25 15:43:36 Stout daphne[1877778]: await self.connect_check_health(check_health=True)
Mar 25 15:43:36 Stout daphne[1877778]: File “/home/csrmedical/venv/lib/python3.12/site-packages/redis/asyncio/connection.py”, line 319, in connect_check_health
Mar 25 15:43:36 Stout daphne[1877778]: raise ConnectionError(exc) from exc
Mar 25 15:43:36 Stout daphne[1877778]: redis.exceptions.ConnectionError: label empty or too long
Here is my consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
from datetime import datetime
import logging
logger = logging.getLogger('app')
class ChatConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.room_group_name = 'chat'
logger.debug(f'ChatConsumer:connect channel: {self.channel_name}')
# Join chat group
logger.debug(f'ChatConsumer:connect, add group: {self.room_group_name} to channel {self.channel_name}')
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
logger.debug(f'ChatConsumer:connect, await accept')
await self.accept()
logger.debug(f'ChatConsumer:connect, accept complete')
async def disconnect(self, close_code):
# Leave chat group
logger.debug(f'ChatConsumer:disconnect channel: {self.channel_name}')
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
async def receive(self, text_data):
logger.debug(f'ChatConsumer:recieve channel: {self.channel_name}')
text_data_json = json.loads(text_data)
message = text_data_json['message']
username = 'Anonymous'
if self.scope['user'].is_authenticated :
username = self.scope['user'].username
logger.debug(f'ChatConsumer:recieve message: {message}, user: {username}')
now = datetime.now().ctime()
# Broadcast message to chat group
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'chat_message',
'message': message,
'username': username,
'date': now,
}
)
async def chat_message(self, event):
logger.debug(f'ChatConsumer:chat_message message: {event['message']}')
message = event['message']
username = event['username']
now = event['date']
await self.send(text_data=json.dumps({
'message': message,
'username': username,
'date': now,
}))
Based on my debug logging, the error is occurring in group_add, but I have no idea what label is empty or too long. It seems like I saw this at one time on my dev system, but have no idea how I fixed it. At this point, I’m not even sure what to look at. I assume it is a configuration error, but beyond that I’m at a loss. Any help is greatly appreciated.
Here is what I think are the relevant settings/configuration
CHANNEL_LAYERS from settings.py
"""
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels.layers.InMemoryChannelLayer"
}
}
"""
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("127.0.0.1", 6379)],
}
}
}
installed packages
asgiref==3.11.0
attrs==25.4.0
autobahn==25.12.2
Automat==25.4.16
cbor2==5.7.1
cffi==2.0.0
channels==4.3.2
channels_redis==4.3.0
constantly==23.10.4
cryptography==46.0.3
daphne==4.2.1
Django==6.0
django-redis==6.0.0
hyperlink==21.0.0
idna==3.11
Incremental==24.11.0
msgpack==1.1.2
packaging==25.0
py-ubjson==0.16.1
pyasn1==0.6.1
pyasn1_modules==0.4.2
pycparser==2.23
pyOpenSSL==25.3.0
redis==7.3.0
service-identity==24.2.0
sqlparse==0.5.5
Twisted==25.5.0
txaio==25.12.2
typing_extensions==4.15.0
ujson==5.11.0
zope.interface==8.1.1
I believe that the only change I made to the default redis.conf was to set supervised to auto.