Skip to main content

Overview

Lavalink uses password-based authentication to secure both REST and WebSocket connections. All API requests must include the configured password in the Authorization header.
Never expose your Lavalink password in client-side code or public repositories. Store it securely in environment variables or configuration files.

Setting the Password

Configure the password in your Lavalink server’s application.yml:
application.yml
lavalink:
  server:
    password: "youshallnotpass"
Use a strong, randomly generated password for production deployments. Consider using environment variables:
lavalink:
  server:
    password: ${LAVALINK_PASSWORD}

REST API Authentication

All REST endpoints (except /version) require the Authorization header.

Required Header

Authorization: youshallnotpass

Example Request

const response = await fetch('http://localhost:2333/v4/info', {
  headers: {
    'Authorization': 'youshallnotpass'
  }
});
import requests

response = requests.get(
    'http://localhost:2333/v4/info',
    headers={'Authorization': 'youshallnotpass'}
)
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("http://localhost:2333/v4/info"))
    .header("Authorization", "youshallnotpass")
    .GET()
    .build();

Unauthorized Response

If authentication fails, Lavalink returns a 401 Unauthorized response:
{
  "timestamp": 1667857581613,
  "status": 401,
  "error": "Unauthorized",
  "message": "Invalid authorization",
  "path": "/v4/info"
}

WebSocket Authentication

WebSocket connections require authentication headers during the initial handshake.

Required Headers

When establishing a WebSocket connection to /v4/websocket, include these headers:
HeaderDescriptionRequiredExample
AuthorizationYour Lavalink passwordYesyoushallnotpass
User-IdDiscord bot user IDYes170939974227541168
Client-NameClient identifier in NAME/VERSION formatYesmy-bot/1.0.0
Session-IdPrevious session ID for resumingNoxtaug914v9k5032f

Connection Example

const WebSocket = require('ws');

const ws = new WebSocket('ws://localhost:2333/v4/websocket', {
  headers: {
    'Authorization': 'youshallnotpass',
    'User-Id': '170939974227541168',
    'Client-Name': 'my-bot/1.0.0'
  }
});

ws.on('open', () => {
  console.log('Connected to Lavalink');
});

ws.on('error', (error) => {
  console.error('WebSocket error:', error);
});

Authentication Failure

If WebSocket authentication fails, the connection is immediately closed with a close code indicating the error.

Resuming Sessions with Authentication

When resuming a session, include the Session-Id header along with authentication:
const ws = new WebSocket('ws://localhost:2333/v4/websocket', {
  headers: {
    'Authorization': 'youshallnotpass',
    'User-Id': '170939974227541168',
    'Client-Name': 'my-bot/1.0.0',
    'Session-Id': 'xtaug914v9k5032f'  // Resume previous session
  }
});

Verifying Session Resumption

Check if resumption succeeded via the response header:
Session-Resumed: true
Or via the ready op payload:
{
  "op": "ready",
  "resumed": true,
  "sessionId": "xtaug914v9k5032f"
}
If the session ID is invalid or expired, Lavalink creates a new session instead of resuming. Check the resumed field to confirm.

Client Name Format

The Client-Name header should follow the format NAME/VERSION:
Client-Name: lavalink-client/2.0.0
Client-Name: my-discord-bot/1.5.3
Client-Name: music-bot-library/3.0.0-beta
This helps identify different clients in Lavalink logs and metrics.

Security Best Practices

Generate a cryptographically secure random password:
# Linux/macOS
openssl rand -base64 32

# Windows PowerShell
-join ((48..57) + (65..90) + (97..122) | Get-Random -Count 32 | % {[char]$_})
Never hardcode passwords. Use environment variables:
const LAVALINK_PASSWORD = process.env.LAVALINK_PASSWORD;

const ws = new WebSocket('ws://localhost:2333/v4/websocket', {
  headers: {
    'Authorization': LAVALINK_PASSWORD,
    // ...
  }
});
For production deployments, use WSS (WebSocket Secure) and HTTPS:
// Secure connection
const ws = new WebSocket('wss://lavalink.example.com/v4/websocket', {
  headers: {
    'Authorization': process.env.LAVALINK_PASSWORD,
    'User-Id': '170939974227541168',
    'Client-Name': 'my-bot/1.0.0'
  }
});

// Secure REST request
fetch('https://lavalink.example.com/v4/info', {
  headers: { 'Authorization': process.env.LAVALINK_PASSWORD }
});
Use firewall rules to limit access to your Lavalink server:
  • Only allow connections from your bot server’s IP
  • Block public internet access
  • Use VPC/private networks when possible
Example firewall rule (iptables):
# Allow only from specific IP
iptables -A INPUT -p tcp --dport 2333 -s YOUR_BOT_SERVER_IP -j ACCEPT
iptables -A INPUT -p tcp --dport 2333 -j DROP
Change your Lavalink password periodically:
  1. Generate a new password
  2. Update application.yml on the server
  3. Restart Lavalink
  4. Update client configuration
  5. Restart client applications
Check Lavalink logs for repeated authentication failures, which may indicate:
  • Misconfigured clients
  • Brute force attacks
  • Compromised credentials
Example log entry:
[WARN] Authentication failed for client from 192.168.1.100

Multi-Client Authentication

Multiple clients can connect to the same Lavalink server using the same password. Each client receives a unique session ID:
// Bot Instance 1
const ws1 = new WebSocket('ws://localhost:2333/v4/websocket', {
  headers: {
    'Authorization': 'youshallnotpass',
    'User-Id': '170939974227541168',  // Bot 1 user ID
    'Client-Name': 'bot1/1.0.0'
  }
});

// Bot Instance 2
const ws2 = new WebSocket('ws://localhost:2333/v4/websocket', {
  headers: {
    'Authorization': 'youshallnotpass',
    'User-Id': '280847363542810624',  // Bot 2 user ID
    'Client-Name': 'bot2/1.0.0'
  }
});
Each connection maintains isolated sessions and players.

Testing Authentication

Verify your authentication is working correctly:

Test REST Authentication

# Valid password - should return version info
curl -H "Authorization: youshallnotpass" http://localhost:2333/v4/info

# Invalid password - should return 401
curl -H "Authorization: wrongpassword" http://localhost:2333/v4/info

# Missing header - should return 401
curl http://localhost:2333/v4/info

Test WebSocket Authentication

const WebSocket = require('ws');

// Test with correct password
const wsValid = new WebSocket('ws://localhost:2333/v4/websocket', {
  headers: {
    'Authorization': 'youshallnotpass',
    'User-Id': '170939974227541168',
    'Client-Name': 'test/1.0.0'
  }
});

wsValid.on('message', (data) => {
  const payload = JSON.parse(data);
  if (payload.op === 'ready') {
    console.log('✓ Authentication successful');
    console.log('Session ID:', payload.sessionId);
  }
});

// Test with incorrect password
const wsInvalid = new WebSocket('ws://localhost:2333/v4/websocket', {
  headers: {
    'Authorization': 'wrongpassword',
    'User-Id': '170939974227541168',
    'Client-Name': 'test/1.0.0'
  }
});

wsInvalid.on('error', (error) => {
  console.log('✗ Authentication failed (expected)');
});

Troubleshooting

Cause: Password mismatch between client and serverSolution:
  1. Check application.yml for the correct password
  2. Verify your client is using the exact same password
  3. Check for extra whitespace or encoding issues
Cause: Missing or invalid authentication headersSolution:
  1. Ensure all three required headers are present
  2. Verify User-Id is a valid Discord user ID (numeric string)
  3. Check Client-Name follows NAME/VERSION format
Cause: Session expired or invalid session IDSolution:
  1. Check if session timeout was exceeded (default 60s)
  2. Verify session ID is correct
  3. Ensure resuming was enabled via Update Session endpoint
  4. Confirm Lavalink server didn’t restart (sessions don’t persist across restarts)
Cause: Lavalink server not binding to public interface or firewall blockingSolution:
  1. Check application.yml server address: server.address: 0.0.0.0
  2. Verify firewall allows port 2333
  3. Test connection: telnet lavalink-server 2333

Next Steps

Implementation Guide

Build your Lavalink client integration

REST API

Explore authenticated endpoints

WebSocket API

Real-time event streaming

Configuration

Configure Lavalink server settings

Build docs developers (and LLMs) love