Troubleshooting¶
This page lists common problems when using Django-AWS-API-Gateway-WebSockets and how to investigate them.
General checklist¶
If something is not working, start with this checklist:
the Django application is reachable over HTTPS;
the API Gateway has been created and deployed;
the API Gateway record in Django has the expected API ID;
the target base endpoint is correct and ends with a trailing slash;
the Django URL includes
<slug:route>;the slug parameter is named
route;AWS credentials are configured correctly;
IAM permissions allow the action you are trying to perform;
DNS points to the correct API Gateway domain;
the browser is connecting with
wss://;WebSocket tokens are configured correctly if enabled;
old sessions, tokens, and rate limit records are being cleaned up.
Connection fails immediately¶
Symptoms¶
The browser cannot open the WebSocket connection.
You may see errors such as:
WebSocket connection failed
or:
Error during WebSocket handshake
Possible causes¶
Common causes include:
incorrect WebSocket URL;
using
https://instead ofwss://;DNS not pointing to API Gateway;
custom domain not configured correctly;
certificate not valid;
API Gateway stage not deployed;
Django endpoint not reachable from API Gateway;
missing or invalid WebSocket token;
API Gateway routes not configured.
What to check¶
Check that the browser connects to a WebSocket URL:
wss://ws.example.com
not:
https://ws.example.com
Check that the custom domain resolves correctly.
Check that the API Gateway record has been created and deployed.
Check that API Gateway can reach your Django endpoint over HTTPS.
Django returns bad request¶
Symptoms¶
The connection reaches Django, but Django rejects it with a bad request.
Possible causes¶
Common causes include:
missing expected headers;
request did not come through API Gateway;
invalid host or origin;
invalid connection ID;
invalid channel name;
missing token;
expired token;
reused token;
route parameter is missing or misnamed.
What to check¶
Confirm that your Django URL pattern contains a slug named route.
path(
"ws/<slug:route>",
ExampleWebSocketView.as_view(),
name="example_websocket",
)
The parameter must be named route.
If using a local tunnel or proxy, check whether expected headers are being removed or rewritten.
Messages always go to the default handler¶
Symptoms¶
Custom handlers are not called. All messages are handled by default.
Possible causes¶
Common causes include:
the client payload does not include the expected handler or action key;
the API Gateway route selection expression does not match the payload;
the Django view uses a different handler selection key;
the custom handler is not included in allowed handlers;
the method name does not match the requested handler name;
the handler name contains characters that are not valid for a Python method.
What to check¶
Check the client payload.
socket.send(JSON.stringify({
action: "chat_message",
message: "Hello"
}));
Check that the Django view has a matching method.
def chat_message(self, request, *args, **kwargs):
return None
If using explicit handler whitelisting, check that the handler is allowed.
ALLOWED_HANDLERS = {
"default",
"chat_message",
}
Custom route is not called¶
Symptoms¶
A custom API Gateway route does not call the expected Django view.
Possible causes¶
Common causes include:
the custom route has not been created;
the API Gateway has not been redeployed;
the route key does not match the client payload;
the additional route integration URL is wrong;
the target Django URL is not reachable;
the route selection expression does not match your message shape.
What to check¶
Confirm that the additional route exists in AWS API Gateway.
Confirm that the API Gateway stage has been redeployed.
Confirm that the client sends the expected route key.
socket.send(JSON.stringify({
action: "notifications",
message: "Hello"
}));
Confirm that the route key is notifications if that is the route you expect.
WebSocket token request fails¶
Symptoms¶
The browser cannot get a WebSocket token.
The token endpoint may return 403 Forbidden.
Possible causes¶
Common causes include:
user is not authenticated;
CSRF token is missing;
CSRF token is invalid;
session cookie is missing;
token generation rate limit has been exceeded;
token endpoint URL is wrong;
cookies are not being sent with the request.
What to check¶
Make sure the request includes:
X-CSRFTokenheader;Django session cookie;
credentials: "same-origin"in the fetch request.
Example:
const response = await fetch("/api/ws-token/", {
method: "POST",
headers: {
"X-CSRFToken": csrfToken,
"Content-Type": "application/json"
},
credentials: "same-origin"
});
See WebSocket tokens.
WebSocket token is rejected during connection¶
Symptoms¶
The token request succeeds, but the WebSocket connection is rejected.
Possible causes¶
Common causes include:
token was not included in the WebSocket URL;
token expired before the connection was opened;
token was already used;
reconnect attempted to reuse an old token;
session cookie changed between token request and connection;
connection is opened from a different browser context.
What to check¶
Check that the URL includes ws_token.
wss://ws.example.com?ws_token=<token>&channel=notifications
Request the token immediately before opening the WebSocket connection.
For reconnects, always request a fresh token.
Rate limit exceeded¶
Symptoms¶
Connections or token requests are rejected after repeated attempts.
Possible causes¶
Common causes include:
reconnect loop is too aggressive;
frontend repeatedly requests tokens;
multiple tabs are open;
connection attempts are failing and retrying rapidly;
legitimate usage exceeds the configured limits;
abuse or automated traffic.
What to check¶
Check the reconnect settings in the browser.
Avoid rapid reconnect loops.
If using reconnecting-websocket, use backoff settings.
const socket = new ReconnectingWebSocket(websocketUrl, null, {
debug: false,
reconnectInterval: 3000,
maxReconnectInterval: 10000,
reconnectDecay: 1.5,
timeoutInterval: 5000,
maxReconnectAttempts: null
});
If legitimate clients are being limited, adjust the view settings.
class ExampleWebSocketView(WebSocketView):
RATE_LIMIT_ENABLED = True
RATE_LIMIT_MAX_ATTEMPTS = 40
RATE_LIMIT_WINDOW_MINUTES = 5
See Rate limiting.
User is anonymous unexpectedly¶
Symptoms¶
The WebSocket view receives an anonymous user when an authenticated user was expected.
Possible causes¶
Common causes include:
WebSocket token protection is disabled;
token request was made anonymously;
session cookie is not available to the WebSocket endpoint;
cookie domain does not cover the WebSocket subdomain;
session expired;
user logged out before connecting;
custom domain setup uses a different parent domain.
What to check¶
If your site is:
https://www.example.com
and your WebSocket endpoint is:
wss://ws.example.com
review your cookie settings.
You may need to configure:
SESSION_COOKIE_DOMAIN;CSRF_COOKIE_DOMAIN;CSRF_TRUSTED_ORIGINS;SESSION_COOKIE_SAMESITE;CSRF_COOKIE_SAMESITE.
See Configuration and API Gateway Setup.
Permission denied¶
Symptoms¶
The connection works, but a message handler returns permission denied.
Possible causes¶
Common causes include:
user does not have the required Django permission;
view-level permissions are too strict;
handler-level permission check fails;
user is connected to a channel they cannot access;
object-level access check fails.
What to check¶
Check the user’s Django permissions.
Check the view configuration.
class ExampleWebSocketView(WebSocketView):
permissions_required = [
"chat.can_use_chat",
]
For object-level access, check your handler logic.
See Permissions.
Messages are not received by the browser¶
Symptoms¶
Django sends a message, but the browser does not receive it.
Possible causes¶
Common causes include:
the connection is no longer active;
the message was sent to the wrong channel;
the session has
connected=False;stale session records exist;
AWS returned a gone connection response;
the browser’s
onmessagehandler has an error;the message is not valid JSON for your frontend handler;
the user changed rooms and is now on another channel.
What to check¶
Check that the queryset targets the expected channel.
WebSocketSession.objects.filter(
channel_name="general",
).send_message(
{
"type": "chat_message",
"message": "Hello",
}
)
Check the browser console for JavaScript errors.
Check that stale sessions are being cleaned up.
See Clean-up.
GoneException when sending messages¶
Symptoms¶
AWS reports that a connection has gone away when Django tries to send a message.
Possible causes¶
This usually means the client is no longer connected.
Common causes include:
browser tab was closed;
network disconnected;
API Gateway timed out the connection;
client changed rooms;
stale session still exists in the database.
What to check¶
Treat gone connections as normal operational behaviour.
Make sure cleanup is scheduled.
See Clean-up.
Messages fail because they are too large¶
Symptoms¶
Sending a message fails when the payload is large.
Possible causes¶
AWS API Gateway WebSocket messages have size limits.
What to check¶
Keep WebSocket messages small.
For large payloads, send a lightweight notification and let the browser fetch the full data over HTTPS.
Example:
{
"type": "report_ready",
"report_id": 123,
"fetch_url": "/reports/123/"
}
Local development does not work¶
Symptoms¶
The application works in production but not locally, or API Gateway cannot reach the local Django server.
Possible causes¶
Common causes include:
local server is not publicly reachable;
local server is not using HTTPS;
tunnel URL changed;
API Gateway target endpoint still points to an old URL;
tunnel strips or rewrites headers;
Django
ALLOWED_HOSTSdoes not include the tunnel host.
What to check¶
Use a tunnelling service to expose your local server over HTTPS.
Update the API Gateway target base endpoint to the tunnel URL.
Check ALLOWED_HOSTS and CSRF settings.
See Local development.
Custom domain does not work¶
Symptoms¶
The generated API Gateway endpoint works, but the custom domain does not.
Possible causes¶
Common causes include:
certificate is not validated;
certificate does not cover the WebSocket domain;
DNS record points to the wrong target;
API mapping was not created;
custom domain is in the wrong AWS region;
stage mapping is incorrect.
What to check¶
Check the API Gateway record for the API Gateway domain name.
Check your DNS provider.
Check the certificate in AWS Certificate Manager.
Check that the custom domain is mapped to the expected API and stage.
API Gateway creation fails¶
Symptoms¶
The admin action or management command fails when creating API Gateway resources.
Possible causes¶
Common causes include:
missing IAM permissions;
incorrect AWS region;
invalid target base endpoint;
invalid certificate ARN;
invalid domain name;
AWS service-linked role permission issue;
credentials are not available to Django.
What to check¶
Check AWS credentials.
Check the configured AWS region.
Check the IAM policy.
See AWS IAM Setup.
Management command cannot send or create resources¶
Symptoms¶
Management commands fail locally or in deployment.
Possible causes¶
Common causes include:
virtual environment is not active;
Django settings module is not configured;
AWS credentials are missing;
wrong AWS profile is selected;
IAM permissions are insufficient;
command arguments are incorrect.
What to check¶
Check that you can run normal Django commands first.
Check the configured AWS credential method.
Check the primary key passed to API Gateway commands.
Example:
python manage.py createApiGateway --pk=1
Debugging WebSocket views¶
You can enable debug behaviour on the view during development.
Example:
path(
"ws/<slug:route>",
ExampleWebSocketView.as_view(debug=True),
name="example_websocket",
)
Do not expose detailed debugging information to users in production.
Cleanup problems¶
Symptoms¶
The database contains many old sessions, tokens, or rate limit records.
Possible causes¶
Common causes include:
cleanup commands are not scheduled;
scheduled task is using the wrong environment;
command name or arguments are wrong;
task runner cannot access the Django project;
stale sessions are expected but not being pruned.
What to check¶
Run cleanup manually first.
python manage.py clearWebSocketSessions
python manage.py cleanupWebSocketTokens --token-age=300 --rate-limit-age=7
Then schedule the commands using cron, Celery Beat, a container scheduler, or your platform’s scheduled task system.
See Clean-up.
Getting more information¶
When debugging, collect:
browser console errors;
browser network WebSocket details;
API Gateway logs;
Django logs;
API Gateway record values;
WebSocket session records;
token records;
rate limit records;
AWS region and account details;
custom domain and DNS values.