You set up Jitsi Meet, you open a conference, and then… nothing. The page loads, you can join, but the moment someone turns on their camera you get “Something went wrong”, or the call simply never connects audio and video. The web app works, signalling works, but media is dead.
Nine times out of ten this is the same problem: your videobridge is not connecting to Jicofo. Jicofo does not know any bridge exists, so it has nothing to route media through.
This tutorial is for anyone who already has a working Jitsi Meet install and is now staring at a conference that refuses to send video.
Scope: this guide covers a native package install of Jitsi, the kind you get from
apt install jitsi-meeton Ubuntu, managed withsystemctl. It is not for the Docker (docker-jitsi-meet) setup. The underlying concepts here, the brewery room,brewery-jid,muc_jids, are exactly the same on Docker, but the commands are different (you would usedocker composeanddocker logs, and configure things through environment variables in a.envfile instead of editing config files on the host).
By the end you will understand what the brewery-jid and muc_jids settings actually do, how to confirm whether your bridge is connected, and how to fix the three or four mistakes that cause almost every “bridge not connecting” report.
How Jitsi Components Talk to Each Other
Before touching any config file, you need a mental picture of what is happening. Jitsi has three moving parts that matter here:
- Prosody: the XMPP server. Think of it as a chat server. Everything in Jitsi talks through Prosody, not directly to each other.
- Jicofo: the “conference focus”. It decides who joins which call and, importantly, which videobridge handles the media.
- JVB (Jitsi Videobridge): the component that actually forwards audio and video between participants.
The clever part is how Jicofo finds the videobridges. It does not have a hardcoded list of bridge IP addresses. Instead, Jitsi uses a chat room.
When a videobridge starts, it logs into Prosody and joins a special, hidden chat room called the brewery room (sometimes called the JVB brewery MUC, MUC just means “multi-user chat”, a group chat room). Jicofo also sits inside that same room, watching who comes and goes. Every time a bridge joins the room, Jicofo sees it appear and adds it to its list of usable bridges. When a bridge leaves, Jicofo removes it.
So the whole system depends on one agreement: Jicofo and every videobridge must point at the exact same room address. That room address is configured in two places:
- On Jicofo, it is called
brewery-jid. - On the videobridge, it is called
muc_jids.
A JID (“Jabber ID”) is just an XMPP address. It looks like an email address: [email protected]. The part before the @ is the room name, and the part after is the XMPP domain it lives on.
If brewery-jid on Jicofo and muc_jids on the bridge do not match character-for-character, Jicofo and the bridge end up in two different rooms. Neither sees the other. Jicofo reports zero bridges, and every conference fails. That single mismatch is the most common cause of this whole problem.
Prerequisites
This is a troubleshooting guide, so the assumption is that you already have things installed. You will need:
- A working Jitsi Meet installation on Ubuntu 22.04 or 24.04 (the steps also apply to 20.04 and to multi-server setups).
- Root or
sudoaccess on the server running Jicofo, and on every server running a videobridge. - Basic comfort with the Linux command line: editing files with
nano, reading logs, restarting services. - Knowing your Jitsi domain (your FQDN, for example
meet.example.com).
To make the commands shorter, become root first:
sudo su
Step 1: Confirm the Bridge Is Actually Disconnected
Do not guess. Before changing anything, confirm the diagnosis. Run this on the Jicofo server:
grep "Added new videobridge" /var/log/jitsi/jicofo.log
If the bridge is healthy, you will see one line per bridge, something like this:
Jicofo 2024-... INFO: Added new videobridge: Jvb[jvb-1, ...]
If that command prints nothing, Jicofo has no bridges. That confirms the problem.
You can also ask Jicofo directly over its built-in stats endpoint. On the Jicofo server:
curl http://localhost:8888/stats | python3 -m json.tool | grep -i bridge
Look at the bridge_count value. If it is 0, no bridge has joined the brewery room:
"bridge_count": 0,
"bridge_selector": {
"bridge_count": 0,
"operational_bridge_count": 0
}
When bridge_count is 0, your job is to figure out why the bridge never made it into the room. The next steps walk through the causes in the order they usually happen.
Step 2: Check Whether the Bridge Process Is Even Running
A bridge that crashed cannot join any room. On the JVB server:
systemctl status jitsi-videobridge2
You want to see active (running). If you see failed or activating (auto-restart), the bridge is crash-looping. Look at why:
journalctl -u jitsi-videobridge2 -n 50 --no-pager
A very common cause of a crash loop is Java not being installed or being the wrong version. Modern Jitsi Videobridge needs Java 11 or newer. Check it:
java -version
If that command is “not found”, install a JDK and restart the bridge:
apt update && apt install default-jdk
systemctl restart jitsi-videobridge2
Only continue once the bridge process stays running for more than a minute or two.
Step 3: Find Out Which Config Format Your Bridge Uses
This is the step that trips people up, because Jitsi changed its configuration style and both formats still exist in the wild.
- Old style: settings live in
/etc/jitsi/videobridge/sip-communicator.propertiesas flat lines likeorg.jitsi.videobridge.xmpp.user.shard.muc_jids=.... This format is now deprecated but still works on older installs. - New style: settings live in
/etc/jitsi/videobridge/jvb.confin a nested format called HOCON, wheremuc_jidssits insidevideobridge { apis { xmpp-client { configs { ... } } } }.
You may have both files. The HOCON file (jvb.conf) wins when a setting appears in both. So if you edit sip-communicator.properties and nothing changes, that is your answer, the value in jvb.conf is overriding it.
Run this on the JVB server to see what you actually have:
ls -la /etc/jitsi/videobridge/
Decide which file is the “real” one for your install, and make all your edits there. Mixing the two is a reliable way to confuse yourself for an hour.
Step 4: Compare the Brewery Address on Both Sides
This is the heart of the fix. You are going to read the room address from Jicofo and from the bridge, and check that they are identical.
On the Jicofo server, open the Jicofo config:
nano /etc/jitsi/jicofo/jicofo.conf
Find the brewery-jid line inside the bridge block:
jicofo {
bridge {
brewery-jid: "[email protected]"
}
}
Write that value down exactly. Every character matters.
On the JVB server, read the matching value. If you are on the new format (jvb.conf):
grep -A1 muc_jids /etc/jitsi/videobridge/jvb.conf
You are looking for something like:
muc_jids = "[email protected]"
If you are on the old format (sip-communicator.properties):
grep MUC_JIDS /etc/jitsi/videobridge/sip-communicator.properties
org.jitsi.videobridge.xmpp.user.shard.MUC_JIDS=jvbbrewery@internal.auth.meet.example.com
Now put the two values side by side. They must match exactly. Watch for these specific traps:
- A typo in the domain.
internal.auth.meet.example.comversusinternal-auth.meet.example.com. Hyphen versus dot is a different domain. - A missing word.
internal.authversus justauth. The brewery domain is almost alwaysinternal.auth.<your-domain>, notauth.<your-domain>. - Case differences.
JvbBreweryversusjvbbrewery. The room name is case sensitive. Pick one spelling and use it on both sides. - A stale example domain. Many people copy a tutorial and forget to replace
meet.example.comwith their real domain on one of the two servers.
If they differ, fix the bridge side to match Jicofo (or the other way around, just make them identical), save, and restart the bridge:
systemctl restart jitsi-videobridge2
Then re-run the check from Step 1. If bridge_count is still 0, the addresses match but the bridge cannot log in, that is the next step.
Step 5: Check the Bridge Login Credentials
The bridge cannot join the brewery room if it cannot log into Prosody in the first place. It logs in as a normal XMPP user, usually jvb, with a password.
On the JVB server, find the credentials. New format:
grep -E "domain|username|password|hostname" /etc/jitsi/videobridge/jvb.conf
Old format:
grep -E "DOMAIN|USERNAME|PASSWORD|HOSTNAME" /etc/jitsi/videobridge/sip-communicator.properties
You will see four important values:
hostname: the address of the Prosody server. On a single server this islocalhost. On a multi-server setup it must be the main server’s domain or IP, reachable over the network.domain: the XMPP auth domain, normallyauth.<your-domain>.username: normallyjvb.password: the secret for thatjvbuser.
The password must match the password of the jvb user that exists inside Prosody. On the Prosody server (the main server), check that the user exists:
prosodyctl mod_listusers | grep jvb
If the jvb user is missing, or you are not sure the password matches, the cleanest fix is to set a known password on Prosody and copy it into the bridge config. On the Prosody server:
prosodyctl passwd [email protected]
It will prompt you for a new password twice. Use that exact password in the bridge’s password field, then restart the bridge.
A quick way to confirm a login failure is to watch the bridge log while it starts:
journalctl -u jitsi-videobridge2 -f
Restart the bridge in another terminal. If you see lines mentioning not-authorized or failed to connect, the credentials or the hostname are wrong.
Step 6: Check Network and Firewall (Multi-Server Only)
If Jicofo and the bridge are on different servers, the bridge needs to reach Prosody over the network on the XMPP client port, which is TCP 5222.
From the JVB server, test that the port is open on the main server:
nc -zv meet.example.com 5222
A healthy result says succeeded or open. If it hangs or says refused, a firewall is blocking it. On the main server, allow the port:
ufw allow 5222/tcp
While you are here: on a multi-server setup the bridge config’s hostname must be the main server, not localhost. Setting hostname to localhost on a separate JVB server means the bridge tries to find Prosody on itself, where Prosody is not running. This is an extremely common copy-paste mistake when someone adapts a single-server config for a second machine.
Step 7: Restart in the Right Order and Verify
After any config change, restart the services. Order matters a little: bring up Prosody first, then Jicofo, then the bridges.
On the main server:
systemctl restart prosody
systemctl restart jicofo
On each JVB server:
systemctl restart jitsi-videobridge2
Give it about 15 seconds, then run the check from Step 1 again:
grep "Added new videobridge" /var/log/jitsi/jicofo.log
Seeing a fresh Added new videobridge line with a recent timestamp means the bridge has joined the brewery room and Jicofo can see it. Open a test conference with two devices and confirm that video flows.
Common Mistakes and Troubleshooting
“I fixed the config but nothing changed.”
You almost certainly edited sip-communicator.properties while jvb.conf has its own value that overrides it. Re-read Step 3 and edit the file that actually wins.
“bridge_count went from 0 to 1 and then back to 0.”
The bridge joined and then crashed or was kicked. Watch journalctl -u jitsi-videobridge2 -f during a restart and read the error. This is often a certificate problem, see the next point.
Certificate verification errors.
On a multi-server setup the bridge connects to Prosody over TLS, and a self-signed or mismatched certificate makes the login fail. For an internal-only XMPP connection that is not exposed to the public, the standard workaround is to disable certificate verification for that connection. New format, inside the relevant xmpp-client config block in jvb.conf:
disable-certificate-verification = true
Old format in sip-communicator.properties:
org.jitsi.videobridge.xmpp.user.shard.DISABLE_CERTIFICATE_VERIFICATION=true
Two bridges, only one shows up.
Each bridge must have a unique muc_nickname. If you cloned a server, both bridges have the same nickname, they collide in the brewery room, and only one survives. Give each bridge a distinct nickname (jvb-1, jvb-2, or a random string) and restart.
Jicofo log says nothing at all.
Confirm you are reading the right file (/var/log/jitsi/jicofo.log) and that Jicofo itself is running with systemctl status jicofo. A Jicofo that is not running cannot log anything.
Editing the wrong server’s config.
In a multi-server setup it is easy to SSH into the JVB box and edit jicofo.conf out of habit, except Jicofo is not even installed there. Always check hostname in your shell prompt before editing.
Best Practices
Treat the brewery address as one fact, not two settings. Decide on the exact JID once, write it in a note, and paste the identical string into Jicofo and every bridge. Never type it twice from memory.
Migrate to the jvb.conf (HOCON) format. The old sip-communicator.properties style is deprecated. New installs use HOCON, and most current documentation assumes it. Staying on the old format means future tutorials will not match what you see.
Give every bridge a unique, meaningful muc_nickname from day one. jvb-frankfurt-1 is far more useful in logs than a random hash.
Keep XMPP traffic private. Port 5222 between Jicofo and the bridges should be reachable by your own servers only, not open to the whole internet. Lock it down with ufw or a cloud security group.
After any change, always verify with bridge_count, not with hope. A two-second curl to the stats endpoint tells you the truth; assuming it worked does not.
Conclusion
A Jitsi videobridge that “will not connect” is almost never a deep or mysterious failure. It is one of a small set of concrete mistakes: the bridge process is down, the brewery-jid and muc_jids addresses do not match, the login password is wrong, or a firewall is blocking port 5222 between servers.
The reliable way through it is to stop guessing and check in order, is the process running, do the brewery addresses match exactly, can the bridge log in, can it reach Prosody over the network, and to verify each fix with bridge_count rather than assuming. Once you understand that Jicofo discovers bridges through a shared chat room, the whole thing stops feeling like magic.
From here, good next steps are scaling out: once a single bridge connects cleanly, adding more is just repeating Steps 4 to 7 with a fresh muc_nickname each time.