Troubleshooting

This guide will help solve common problems when using VibeMQ.

Connection Issues

“Connection refused”

Error:

System.Net.Sockets.SocketException: Connection refused

Causes:

  1. Server not running

  2. Wrong port

  3. Firewall blocking connection

  4. Server listening only on localhost

Solution:

// Check that server is running
var broker = BrokerBuilder.Create()
    .UsePort(2925)  // Correct port
    .Build();

await broker.RunAsync(cancellationToken);

// Check that client connects to correct port
var client = await VibeMQClient.ConnectAsync("localhost", 2925);

Check:

# Check that port is listening
netstat -an | grep 2925

# PowerShell
Get-NetTCPConnection -LocalPort 2925

“Connection timeout”

Error:

System.TimeoutException: Connection timeout

Causes:

  1. Network latency

  2. Server overloaded

  3. Wrong timeout

Solution:

var client = await VibeMQClient.ConnectAsync(
    "localhost",
    2925,
    new ClientOptions {
        CommandTimeout = TimeSpan.FromSeconds(30)  // Increase timeout
    }
);

“Host unreachable”

Error:

System.Net.Sockets.SocketException: Host unreachable

Causes:

  1. Wrong host

  2. Network issues

  3. DNS not resolving

Solution:

// Check host
var client = await VibeMQClient.ConnectAsync(
    "vibemq-server",  // Correct hostname
    2925
);

DNS check:

nslookup vibemq-server
ping vibemq-server

Authentication Issues

“Authentication failed”

Error:

Authentication failed: Invalid username or password

Cause: Username/password on server and client do not match.

Solution:

// Server
var broker = BrokerBuilder.Create()
    .UseAuthorization(options => {
    options.SuperuserUsername = "admin";
    options.SuperuserPassword = "my-secret-password";
})  // same credentials
    .Build();

// Client
var client = await VibeMQClient.ConnectAsync(
    "localhost",
    2925,
    new ClientOptions { Username = "admin", Password = "my-secret-password"  // same credentials
     }
);

Warning

Credentials are case-sensitive!

“Authentication required”

Error:

Authentication required: Username and password not provided

Cause: Server requires authentication, but client did not provide username/password.

Solution:

var client = await VibeMQClient.ConnectAsync(
    "localhost",
    2925,
    new ClientOptions { Username = "admin", Password = "my-password"  // Provide credentials
     }
);

Queue Issues

“Queue not found”

Error:

Queue not found: notifications

Causes:

  1. Queue does not exist

  2. Auto-create disabled

Solution 1: Enable auto-create:

.ConfigureQueues(options => {
    options.EnableAutoCreate = true;
});

Solution 2: Create queue manually:

await client.CreateQueueAsync("notifications", new QueueOptions {
    Mode = DeliveryMode.RoundRobin,
    MaxQueueSize = 10_000
});

“Queue already exists”

Error:

Queue already exists: notifications

Cause: Attempting to create existing queue.

Solution:

try {
    await client.CreateQueueAsync("notifications");
} catch (InvalidOperationException ex) when (ex.Message.Contains("CreateQueue failed")) {
    // Queue may already exist or server returned an error
}

Message Delivery Issues

Messages Not Delivered

Problem: Messages are published but subscribers do not receive them.

Possible causes:

  1. Subscriber not subscribed to queue

  2. Wrong queue name

  3. Network issues

Solution:

// Check queue name
await client.PublishAsync("notifications", message);  // Same name

await using var subscription = await client.SubscribeAsync<dynamic>(
    "notifications",  // Same name
    async msg => { /* processing */ }
);

Check:

var info = await client.GetQueueInfoAsync("notifications");
Console.WriteLine($"Subscribers: {info?.SubscriberCount}");

Slow Message Delivery

Problem: High delivery latency.

Causes:

  1. Server overload

  2. Slow handlers

  3. Network delays

Solution:

// Optimize handler
await using var subscription = await client.SubscribeAsync<dynamic>(
    "notifications",
    async msg => {
        // Fast processing
        await ProcessFastAsync(msg);

        // Or async processing in background
        _ = Task.Run(() => ProcessInBackgroundAsync(msg));
    }
);

Monitor latency:

curl http://localhost:2926/metrics/ | jq .average_delivery_latency_ms

“Message timeout”

Error:

Message timeout: No ACK received

Cause: Subscriber did not send ACK within timeout.

Solution:

// When creating the queue, set TTL (server queue defaults do not include TTL)
await client.CreateQueueAsync("notifications", new QueueOptions {
    MessageTtl = TimeSpan.FromMinutes(1)
});

// Ensure handler is fast
await using var subscription = await client.SubscribeAsync<dynamic>(
    "notifications",
    async msg => {
        try {
            await ProcessMessageAsync(msg);
            // ACK sent automatically
        } catch (Exception ex) {
            // Error handling
            throw;  // For retry
        }
    }
);

Memory Issues

“Out of memory”

Error:

System.OutOfMemoryException

Causes:

  1. Queues too large

  2. Many unacknowledged messages

  3. Memory leaks

Solution:

// Limit queue sizes (defaults for auto-created queues)
.ConfigureQueues(options => {
    options.MaxQueueSize = 10_000;
});

// When creating a queue, enable DLQ and set TTL/retries
await client.CreateQueueAsync("notifications", new QueueOptions {
    MaxQueueSize = 10_000,
    MessageTtl = TimeSpan.FromHours(1),
    EnableDeadLetterQueue = true,
    MaxRetryAttempts = 3
});

Monitor memory:

curl http://localhost:2926/health/ | jq .memory_usage_mb

Backpressure

Problem: Publications are blocked.

Cause: Backpressure enabled due to high memory usage.

Solution:

// Reduce default queue size; set overflow strategy when creating queues
.ConfigureQueues(options => {
    options.MaxQueueSize = 5_000;
});
// When creating a queue: new QueueOptions { OverflowStrategy = OverflowStrategy.DropOldest }

Reconnection Issues

Frequent Disconnections

Problem: Client frequently disconnects.

Causes:

  1. Network issues

  2. Server restarting

  3. Keep-alive timeout

Solution:

var client = await VibeMQClient.ConnectAsync(
    "localhost",
    2925,
    new ClientOptions {
        ReconnectPolicy = new ReconnectPolicy {
            MaxAttempts = 50,  // Increase attempts
            InitialDelay = TimeSpan.FromSeconds(2),
            MaxDelay = TimeSpan.FromMinutes(1),
            UseExponentialBackoff = true
        },
        KeepAliveInterval = TimeSpan.FromSeconds(30)  // Keep-alive
    }
);

“Max reconnect attempts exceeded”

Error:

Max reconnect attempts exceeded

Cause: Reconnection attempts exhausted.

Solution:

// Increase attempts or handle error
try {
    var client = await VibeMQClient.ConnectAsync(
        "localhost",
        2925,
        new ClientOptions {
            ReconnectPolicy = new ReconnectPolicy {
                MaxAttempts = 100  // Increase
            }
        }
    );
} catch (InvalidOperationException) {
    // Reconnection attempts exhausted or other error
    Console.WriteLine("Failed to connect. Check server.");
}

TLS/SSL Issues

“Certificate validation failed”

Error:

The remote certificate is invalid according to the validation procedure

Causes:

  1. Self-signed certificate

  2. Certificate expired

  3. Wrong hostname

Solution (tests only):

var client = await VibeMQClient.ConnectAsync(
    "localhost",
    2925,
    new ClientOptions {
        UseTls = true,
        SkipCertificateValidation = true  // Tests only!
    }
);

Solution (production):

# Create valid certificate
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

Warning

Do not use SkipCertificateValidation = true in production!

“TLS handshake failed”

Error:

TLS handshake failed

Causes:

  1. Server not configured for TLS

  2. Wrong certificate

Solution:

// Server
.UseTls(options => {
    options.Enabled = true;
    options.CertificatePath = "/path/to/cert.pfx";
    options.CertificatePassword = "password";
});

// Client
new ClientOptions {
    UseTls = true
};

Rate Limiting Issues

“Rate limit exceeded”

Error:

Rate limit exceeded: Too many messages

Cause: Message limit exceeded.

Solution:

// Increase limit on server
.ConfigureRateLimiting(options => {
    options.MaxMessagesPerClientPerSecond = 5000;  // Increase
});

// Or reduce send frequency on client
await client.PublishAsync("queue", message);
await Task.Delay(100);  // Pause between messages

“Too many connections”

Error:

Too many connections from this IP

Cause: Connection limit exceeded.

Solution:

// Increase limit on server
.ConfigureRateLimiting(options => {
    options.MaxConnectionsPerIpPerWindow = 500;  // Increase
});

Diagnostics

Enabling Verbose Logging

using Microsoft.Extensions.Logging;

using var loggerFactory = LoggerFactory.Create(builder => {
    builder
        .SetMinimumLevel(LogLevel.Debug)  // Verbose logging
        .AddConsole()
        .AddDebug();
});

var broker = BrokerBuilder.Create()
    .UsePort(2925)
    .UseLoggerFactory(loggerFactory)
    .Build();

Health Check

# Health check
curl http://localhost:2926/health/

# Metrics
curl http://localhost:2926/metrics/ | jq

Queue Check

var queues = await client.ListQueuesAsync();

foreach (var queueName in queues) {
    var info = await client.GetQueueInfoAsync(queueName);
    Console.WriteLine($"{queueName}: {info?.MessageCount} messages, {info?.SubscriberCount} subscribers");
}

Connection Check

Console.WriteLine($"Active connections: {broker.ActiveConnections}");
Console.WriteLine($"Messages in flight: {broker.InFlightMessages}");

Next Steps