Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

GitHub

This documentation is part of the "Projects with Books" initiative at zenOSmosis.

The source code for this project is available on GitHub.

Troubleshooting

Loading…

Troubleshooting

Relevant source files

Purpose and Scope

This page provides diagnostic procedures and solutions for common issues encountered when deploying and operating the Docker MQTT Mosquitto with Cloudflare Tunnel system. It covers container startup failures, connection problems, configuration errors, and debugging techniques.

For information about the CI/CD automated health checks, see Continuous Integration. For production monitoring strategies, see Monitoring and Health Checks. For initial setup procedures, see Getting Started.


Diagnostic Decision Tree

The following flowchart provides a systematic approach to diagnosing system issues:

Sources : README.md:74-84 docker-compose.yml:1-18 mosquitto.conf:1-6

flowchart TD
 
   Start["Issue Reported"] --> CheckContainers{"docker compose ps\nAll containers running?"}
CheckContainers -->|No| IdentifyDown{"Which container\nis down?"}
CheckContainers -->|Yes| CheckTunnel["Check tunnel connectivity"]
IdentifyDown -->|mosquitto| MosquittoDown["Check mosquitto logs:\ndocker compose logs mosquitto"]
IdentifyDown -->|cloudflared| CloudflaredDown["Check cloudflared logs:\ndocker compose logs cloudflared"]
IdentifyDown -->|Both| BothDown["Check docker-compose.yml\nand .env configuration"]
MosquittoDown --> MosquittoErrors{"Error type?"}
MosquittoErrors -->|Config syntax| CheckMosquittoConf["Validate mosquitto.conf:1-5\nlistener directives"]
MosquittoErrors -->|Port binding| CheckPortConflict["Check port 1883/9001\nconflicts on host"]
MosquittoErrors -->|Volume mount| CheckVolumeMount["Verify ./mosquitto.conf\nfile exists and readable"]
CloudflaredDown --> CloudflaredErrors{"Error type?"}
CloudflaredErrors -->|Authentication failed| CheckToken["Verify CLOUDFLARE_TUNNEL_TOKEN\nin .env file"]
CloudflaredErrors -->|Tunnel not found| RecreateToken["Generate new token\nin Cloudflare dashboard"]
CloudflaredErrors -->|Connection refused| CheckNetwork["Verify internet connectivity\nand firewall rules"]
BothDown --> CheckDockerCompose["Validate docker-compose.yml\nsyntax and structure"]
CheckTunnel --> TunnelTest{"Can connect via\npublic hostname?"}
TunnelTest -->|No| CheckHostname["Verify hostname in\nCloudflare dashboard\npoints to mosquitto:9001"]
TunnelTest -->|Yes| CheckMQTT["Test MQTT connection\non port 443"]
CheckMQTT --> MQTTTest{"MQTT publish/\nsubscribe works?"}
MQTTTest -->|No| CheckProtocol["Verify protocol:\nWebSockets required\nfor tunnel connection"]
MQTTTest -->|Yes| Resolved["Issue resolved"]
CheckMosquittoConf --> Restart["docker compose restart mosquitto"]
CheckPortConflict --> StopConflicting["Stop conflicting service\nor change port mapping"]
CheckVolumeMount --> FixMount["Create/fix mosquitto.conf\nand verify path"]
CheckToken --> UpdateEnv["Update .env and\ndocker compose restart cloudflared"]
RecreateToken --> UpdateEnv
 
   CheckNetwork --> FixNetwork["Check DNS/firewall/proxy"]
CheckDockerCompose --> FixCompose["Fix syntax errors\nand docker compose up"]
CheckHostname --> UpdateHostname["Update hostname config\nin Cloudflare dashboard"]
CheckProtocol --> UseWebSockets["Use wss:// protocol\non port 443"]
Restart --> Resolved
 
   StopConflicting --> Resolved
 
   FixMount --> Resolved
 
   UpdateEnv --> Resolved
 
   FixNetwork --> Resolved
 
   FixCompose --> Resolved
 
   UpdateHostname --> Resolved
 
   UseWebSockets --> Resolved

Common Issues and Solutions

Container Startup Failures

IssueSymptomsDiagnosisSolution
Missing tunnel tokencloudflared container exits immediatelydocker compose logs cloudflared shows authentication errorCreate .env file from .env.sample template and populate CLOUDFLARE_TUNNEL_TOKEN
Invalid tokencloudflared shows “tunnel credentials invalid”Token rejected by Cloudflare APIGenerate new token in Cloudflare Zero Trust dashboard and update .env
Configuration syntax errormosquitto container crashes on startupdocker compose logs mosquitto shows parse errorValidate mosquitto.conf:1-6 syntax, ensure listener directives are properly formatted
Port conflictmosquitto fails to bind portsError: “Address already in use”Identify conflicting service with sudo lsof -i :1883 and sudo lsof -i :9001, then stop conflicting service
Volume mount failuremosquitto cannot read configurationPermission denied or file not found errorVerify ./mosquitto.conf exists and has read permissions: ls -l mosquitto.conf
Image pull failureContainer fails to start with image errorCannot pull eclipse-mosquitto:latest or cloudflare/cloudflared:latestCheck Docker Hub connectivity, verify registry access, or use explicit image versions

Sources : docker-compose.yml:4-17 mosquitto.conf:1-6 .env.sample1


Connection and Tunnel Issues

The following diagram illustrates the connection verification process:

Connection Troubleshooting Table :

Failure PointTest CommandExpected ResultFix
Tunnel not established`docker compose logs cloudflaredgrep “Connection established”`Should see “Connection established” message
Mosquitto not listeningdocker compose exec mosquitto netstat -tlnpShould show :1883 and :9001 listenersCheck mosquitto.conf:1-5 configuration, restart container
DNS resolution failuredocker compose exec cloudflared nslookup mosquittoShould resolve to container IPVerify container_name: mosquitto in docker-compose.yml6
Public hostname misconfiguredCheck Cloudflare dashboard tunnel configurationURL should point to mosquitto:9001 with HTTP service typeUpdate hostname configuration in Cloudflare dashboard
WebSocket protocol mismatchClient connection logs show protocol errorClient must use wss:// protocol on port 443Update client to use WebSockets over SSL/TLS

Sources : docker-compose.yml:11-17 mosquitto.conf:4-5 README.md:63-67


Health Check Verification

The CI pipeline implements a health check strategy that can be replicated for manual troubleshooting:

Manual Health Check Procedure :

sequenceDiagram
    participant User as "User/CI System"
    participant Docker as "docker-compose"
    participant MosqContainer as "mosquitto container"
    participant HealthCheck as "Health Check Loop"
    
    User->>Docker: docker-compose up -d mosquitto
    Docker->>MosqContainer: Start container
    MosqContainer->>MosqContainer: Load /mosquitto/config/mosquitto.conf
    MosqContainer->>MosqContainer: Bind listener 1883
    MosqContainer->>MosqContainer: Bind listener 9001
    
    User->>HealthCheck: Start health check loop
    Note over HealthCheck: Max 10 attempts, 10 second intervals
    
    loop Until healthy or max attempts
        HealthCheck->>Docker: docker-compose ps --format json
        Docker-->>HealthCheck: Container status JSON
        HealthCheck->>HealthCheck: Parse 'State' field
        
        alt State == "running"
            HealthCheck-->>User: ✓ Service healthy
        else State != "running"
            HealthCheck->>HealthCheck: Sleep 10 seconds
            HealthCheck->>HealthCheck: Increment attempt counter
        end
    end
    
    alt Max attempts exceeded
        HealthCheck-->>User: ✗ Health check failed after 100s
        User->>Docker: docker-compose logs mosquitto
        Docker-->>User: Error logs
    end

Sources : .github/workflows/ci.yml:17-37 docker-compose.yml:4-9 mosquitto.conf:1-6


Configuration Validation

Validating docker-compose.yml

The following elements must be correctly configured in docker-compose.yml:1-18:

Validation Commands :

Sources : docker-compose.yml:1-18 mosquitto.conf:1-6 .env.sample1


Validating mosquitto.conf

The mosquitto.conf:1-6 file has a simple structure but specific syntax requirements:

LineDirectivePurposeCommon Errors
1listener 1883Native MQTT protocol portMissing port number, invalid port range (1-65535)
2allow_anonymous trueAuthentication settingTypo in allow_anonymous, missing boolean value
3(blank)SeparatorN/A
4listener 9001WebSocket protocol portDuplicate port number, port conflict with line 1
5protocol websocketsProtocol specification for listenerTypo in websockets, missing protocol directive

Validation Procedure :

Sources : mosquitto.conf:1-6


Environment Variable Issues

Missing or Invalid CLOUDFLARE_TUNNEL_TOKEN

The CLOUDFLARE_TUNNEL_TOKEN environment variable is the critical authentication credential for establishing the tunnel connection.

Common Token Issues :

ProblemSymptomRoot CauseSolution
Token not setcloudflared exits with “missing token” error.env file not created or emptyCopy .env.sample1 to .env and populate token
Token syntax errorAuthentication fails immediatelyToken contains extra spaces, newlines, or quotesEnsure token is on single line with no surrounding quotes: CLOUDFLARE_TUNNEL_TOKEN=eyJh...
Token expired/revoked“unauthorized” or “tunnel not found” errorToken regenerated in Cloudflare dashboard or tunnel deletedGenerate new token from Cloudflare dashboard and update .env
Wrong tokenTunnel connects but routes to wrong serviceToken from different tunnel configurationVerify token matches the tunnel name in Cloudflare dashboard
.env not loadedVariable shows as empty in container.env file not in correct directory or not named exactly .envVerify .env is in same directory as docker-compose.yml

Debugging Environment Variables :

Sources : docker-compose.yml:16-17 .env.sample1 README.md53


flowchart TB
    ViewLogs["View Container Logs"]
ViewLogs --> MosqLogs["docker compose logs mosquitto"]
ViewLogs --> CFDLogs["docker compose logs cloudflared"]
ViewLogs --> AllLogs["docker compose logs"]
MosqLogs --> MosqSuccess["Success Indicators"]
MosqLogs --> MosqErrors["Error Indicators"]
MosqSuccess --> MS1["'Opening ipv4 listen socket on port 1883'"]
MosqSuccess --> MS2["'Opening websockets listen socket on port 9001'"]
MosqSuccess --> MS3["'mosquitto version X.X.X running'"]
MosqErrors --> ME1["'Error: Unable to open config file'\n→ Volume mount issue"]
MosqErrors --> ME2["'Error: Invalid bridge parameter'\n→ Config syntax error"]
MosqErrors --> ME3["'Error: Address already in use'\n→ Port conflict"]
CFDLogs --> CFDSuccess["Success Indicators"]
CFDLogs --> CFDErrors["Error Indicators"]
CFDSuccess --> CS1["'Connection established'"]
CFDSuccess --> CS2["'Registered tunnel connection'"]
CFDSuccess --> CS3["'Serving tunnel'"]
CFDErrors --> CE1["'authentication failed'\n→ Invalid token"]
CFDErrors --> CE2["'tunnel not found'\n→ Token/tunnel mismatch"]
CFDErrors --> CE3["'connection refused'\n→ Network issue"]

Log Analysis

Reading Container Logs

Both containers produce diagnostic output that can be analyzed for troubleshooting:

Log Analysis Commands :

Sources : docker-compose.yml:4-17


Network Diagnostics

Docker Network Verification

Both containers must be on the same Docker network for internal DNS resolution to function:

Sources : docker-compose.yml:1-18 README.md64


Cloudflare Dashboard Verification

Issues may originate from misconfiguration in the Cloudflare Zero Trust dashboard:

Configuration ItemLocationExpected ValueCommon Mistakes
Tunnel typeNetworks → Tunnels → Tunnel detailsCloudflaredWrong tunnel type selected
Tunnel statusNetworks → Tunnels → Tunnel list“HEALTHY” with green indicatorShows as “DOWN” if container not running or token invalid
Public hostnameNetworks → Tunnels → Public Hostnames tabSubdomain and domain configuredMissing or incorrect hostname
Service typePublic hostname configurationHTTPHTTPS selected (creates double encryption issue)
Service URLPublic hostname configurationmosquitto:9001Incorrect hostname (e.g., localhost, IP address) or wrong port

Verification Steps :

  1. Navigate to Cloudflare Zero Trust dashboard
  2. Go to Networks → Tunnels
  3. Locate your tunnel and verify status shows “HEALTHY”
  4. Click tunnel name to view details
  5. Check Public Hostname tab for correct configuration:

Sources : README.md:29-72 docker-compose.yml6 mosquitto.conf:4-5


Client Connection Issues

Protocol and Port Requirements

External clients must use WebSockets over SSL/TLS on port 443:

Client ProtocolPortResult
wss://subdomain.domain443✓ Correct - WebSockets over SSL through tunnel
mqtt://subdomain.domain443✗ Wrong protocol - Native MQTT not supported through tunnel
ws://subdomain.domain443✗ Wrong protocol - Non-SSL WebSocket rejected
wss://subdomain.domain1883✗ Wrong port - Port 1883 not exposed through tunnel
mqtt://localhost1883✓ Works only from Docker host (not through tunnel)

Client Configuration Example :

Testing Connection :

Sources : README.md:66-82 mosquitto.conf:4-5


Advanced Debugging Techniques

Container Introspection

Resource Constraints

Complete System Reset

Sources : docker-compose.yml:1-18



Summary of Common Error Messages

Error MessageFile/ComponentLikely CauseSolution Reference
“Address already in use”mosquittoPort 1883 or 9001 conflict[Container Startup Failures](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/Container Startup Failures)
“Unable to open config file”mosquittoVolume mount issue[Container Startup Failures](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/Container Startup Failures)
“authentication failed”cloudflaredInvalid CLOUDFLARE_TUNNEL_TOKEN[Environment Variable Issues](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/Environment Variable Issues)
“tunnel not found”cloudflaredToken/tunnel mismatch[Environment Variable Issues](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/Environment Variable Issues)
“connection refused”cloudflaredNetwork/firewall issue[Network Diagnostics](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/Network Diagnostics)
“protocol error”ClientUsing mqtt:// instead of wss://[Client Connection Issues](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/Client Connection Issues)
“DNS resolution failed”cloudflaredContainer name mismatch[Network Diagnostics](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/Network Diagnostics)
“Invalid bridge parameter”mosquittoConfig syntax error in mosquitto.conf[Configuration Validation](https://github.com/jzombie/docker-mqtt-mosquitto-cloudflare-tunnel/blob/59f1274c/Configuration Validation)

Sources : docker-compose.yml:1-18 mosquitto.conf:1-6 .env.sample1 README.md:1-93

Dismiss

Refresh this wiki

Enter email to refresh