A Matrix homeserver written in Rust

What is Matrix?

Matrix is an open network for secure and decentralized communication. Users from every Matrix homeserver can chat with users from all other Matrix servers. You can even use bridges (also called Matrix appservices) to communicate with users outside of Matrix, like a community on Discord.

What is the goal?

An efficient Matrix homeserver that's easy to set up and just works. You can install it on a mini-computer like the Raspberry Pi to host Matrix for your family, friends or company.

Can I try it out?

Yes! You can test our Conduit instance by opening a client that supports registration tokens such as Element web, Nheko or SchildiChat web and registering on the homeserver. The registration token is "for_testing_only". Don't share personal information. Once you have registered, you can use any other Matrix client to login.

Server hosting for is donated by the Foundation.

What is the current status?

Conduit is Beta, meaning you can join and participate in most Matrix rooms, but not all features are supported and you might run into bugs from time to time.

There are still a few important features missing:

  • E2EE emoji comparison over federation (E2EE chat works)
  • Outgoing read receipts, typing, presence over federation (incoming works)

How can I deploy my own?

If you want to connect an Appservice to Conduit, take a look at the appservices documentation.

How can I contribute?

  1. Look for an issue you would like to work on and make sure no one else is currently working on it.
  2. Tell us that you are working on the issue (comment on the issue or chat in If it is more complicated, please explain your approach and ask questions.
  3. Fork the repo, create a new branch and push commits.
  4. Submit a MR


If you have any questions, feel free to

  • Ask in on Matrix
  • Write an E-Mail to
  • Send an direct message to on Matrix
  • Open an issue on GitLab


If you believe you have found a security issue, please send a message to Timo and/or Matthias on Matrix, or send an email to Please do not disclose details about the issue to anyone else before a fix is released publically.

Thanks to

Thanks to FUTO, Famedly, Prototype Fund (DLR and German BMBF) and all individuals for financially supporting this project.

Thanks to the contributors to Conduit and all libraries we use, for example:

  • Ruma: A clean library for the Matrix Spec in Rust
  • axum: A modular web framework


Conduit is configured using a TOML file. The configuration file is loaded from the path specified by the CONDUIT_CONFIG environment variable.

Note: The configuration file is required to run Conduit. If the CONDUIT_CONFIG environment variable is not set, Conduit will exit with an error.

Note: If you update the configuration file, you must restart Conduit for the changes to take effect

Conduit's configuration file is divided into the following sections:


The global section contains the following fields:

Note: The * symbol indicates that the field is required, and the values in parentheses are the possible values

addressstringThe address to bind to""
portintegerThe port to bind to8000
tlstableSee the TLS configurationN/A
server_name*stringThe server nameN/A
database_backend*stringThe database backend to use ("rocksdb" recommended, "sqlite")N/A
database_path*stringThe path to the database file/dirN/A
db_cache_capacity_mbfloatThe cache capacity, in MB300.0
enable_lightning_boltbooleanAdd ⚡️ emoji to end of user's display nametrue
allow_check_for_updatesbooleanAllow Conduit to check for updatestrue
conduit_cache_capacity_modifierfloatThe value to multiply the default cache capacity by1.0
rocksdb_max_open_filesintegerThe maximum number of open files1000
pdu_cache_capacityintegerThe maximum number of Persisted Data Units (PDUs) to cache150000
cleanup_second_intervalintegerHow often conduit should clean up the database, in seconds60
max_request_sizeintegerThe maximum request size, in bytes20971520 (20 MiB)
max_concurrent_requestsintegerThe maximum number of concurrent requests100
max_fetch_prev_eventsintegerThe maximum number of previous events to fetch per request if conduit notices events are missing100
allow_registrationbooleanOpens your homeserver to public registrationfalse
registration_tokenstringThe token users need to have when registering to your homeserverN/A
allow_encryptionbooleanAllow users to enable encryption in their roomstrue
allow_federationbooleanAllow federation with other serverstrue
allow_room_creationbooleanAllow users to create roomstrue
allow_unstable_room_versionsbooleanAllow users to create and join rooms with unstable versionstrue
default_room_versionstringThe default room version ("6"-"10")"10"
allow_jaegerbooleanAllow Jaeger tracingfalse
tracing_flamebooleanEnable flame tracingfalse
proxytableSee the Proxy configurationN/A
jwt_secretstringThe secret used in the JWT to enable JWT login without it a 400 error will be returnedN/A
trusted_serversarrayThe list of trusted servers to gather public keys of offline servers[""]
logstringThe log verbosity to use"warn"
turn_usernamestringThe TURN username""
turn_passwordstringThe TURN password""
turn_urisarrayThe TURN URIs[]
turn_secretstringThe TURN secret""
turn_ttlintegerThe TURN TTL in seconds86400
emergency_passwordstringSet a password to login as the conduit user in case of emergencyN/A
well_knowntableUsed for delegationSee delegation


The tls table contains the following fields:

  • certs: The path to the public PEM certificate
  • key: The path to the PEM private key


certs = "/path/to/cert.pem"
key = "/path/to/key.pem"


You can choose what requests conduit should proxy (if any). The proxy table contains the following fields


The global option will proxy all outgoing requests. The global table contains the following fields:

  • url: The URL of the proxy server
url = ""

By domain

An array of tables that contain the following fields:

  • url: The URL of the proxy server
  • include: Domains that should be proxied (assumed to be ["*"] if unset)
  • exclude: Domains that should not be proxied (takes precedent over include)

Both include and exclude allow for glob pattern matching.


In this example, all requests to domains ending in .onion and will be proxied via socks://localhost:9050, except for domains ending in .myspecial.onion. You can add as many by_domain tables as you need.

url = "socks5://localhost:9050"
include = ["*.onion", ""]
exclude = ["*.clearnet.onion"]


Note: The following example is a minimal configuration file. You should replace the values with your own.

#server_name = ""

database_backend = "rocksdb"
# This is the only directory where Conduit will save its data
database_path = "/var/lib/matrix-conduit/"

# The port Conduit will be running on. You need to set up a reverse proxy in
# your web server (e.g. apache or nginx), so all requests to /_matrix on port
# 443 and 8448 will be forwarded to the Conduit instance running on this port
# Docker users: Don't change this, you'll need to map an external port to this.
port = 6167

# Max size for uploads
max_request_size = 20_000_000 # in bytes

# Enables registration. If set to false, no users can register on this server.
allow_registration = true

# A static registration token that new users will have to provide when creating
# an account. YOU NEED TO EDIT THIS.
# - Insert a password that users will have to enter on registration
# - Start the line with '#' to remove the condition
registration_token = ""

allow_check_for_updates = true
allow_federation = true

# Enable the display name lightning bolt on registration.
enable_lightning_bolt = true

# Servers listed here will be used to gather public keys of other servers.
# Generally, copying this exactly should be enough. (Currently, Conduit doesn't
# support batched key requests, so this list should only contain Synapse
# servers.)
trusted_servers = [""]

#max_concurrent_requests = 100 # How many requests Conduit sends to other servers at the same time

# Controls the log verbosity. See also [here][0].
# [0]:
#log = "..."

address = "" # This makes sure Conduit can only be reached using the reverse proxy
#address = "" # If Conduit is running in a container, make sure the reverse proxy (ie. Traefik) can reach it.

# Conduit handles the /.well-known/matrix/* endpoints, making both clients and servers try to access conduit with the host
# server_name and port 443 by default.
# If you want to override these defaults, uncomment and edit the following lines accordingly:
#server =
#client =


You can run Conduit on a separate domain than the actual server name (what shows up in user ids, aliases, etc.). For example you can have your users have IDs such as and have aliases like, while actually having Conduit hosted on the domain. This is called delegation.

Conduit has support for hosting delegation files by itself, and by default uses it to serve federation traffic on port 443.

With this method, you need to direct requests to /.well-known/matrix/* to Conduit in your reverse proxy.

This is only recommended if Conduit is on the same physical server as the server which serves your server name (e.g. as servers don't always seem to cache the response, leading to slower response times otherwise, but it should also work if you are connected to the server running Conduit using something like a VPN.

Note: this will automatically allow you to use sliding sync without any extra configuration

To configure it, use the following options in the global.well_known table:

clientStringThe URL that clients should use to connect to Conduithttps://<server_name>
serverStringThe hostname and port servers should use to connect to Conduit<server_name>:443


client = ""
server = ""


Alternatively you can serve static JSON files to inform clients and servers how to connect to Conduit.


For servers to discover how to access your domain, serve a response in the following format for /.well-known/matrix/server:

  "m.server": ""

Where is the domain and 443 is the port Conduit is accessible at.


For clients to discover how to access your domain, serve a response in the following format for /.well-known/matrix/client:

  "m.homeserver": {
    "base_url": ""

Where is the URL Conduit is accessible at.

To ensure that all clients can access this endpoint, it is recommended you set the following headers for this endpoint:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: X-Requested-With, Content-Type, Authorization

If you also want to be able to use sliding sync, look here.


This chapter describes various ways to deploy Conduit.

Generic deployment documentation

Getting help

If you run into any problems while setting up Conduit, write an email to, ask us in or open an issue on GitLab.

Installing Conduit

Although you might be able to compile Conduit for Windows, we do recommend running it on a Linux server. We therefore only offer Linux binaries.

You may simply download the binary that fits your machine. Run uname -m to see what you need. For arm, you should use aarch. Now copy the appropriate url:

Stable/Main versions:

x86_64-unknown-linux-muslStatically linked Debian packagelink
aarch64-unknown-linux-muslStatically linked Debian packagelink
x86_64-unknown-linux-muslStatically linked binarylink
aarch64-unknown-linux-muslStatically linked binarylink
x86_64-unknown-linux-gnuOCI imagelink
aarch64-unknown-linux-muslOCI imagelink

These builds were created on and linked against the glibc version shipped with Debian bullseye. If you use a system with an older glibc version (e.g. RHEL8), you might need to compile Conduit yourself.

Latest/Next versions:

x86_64-unknown-linux-muslStatically linked Debian packagelink
aarch64-unknown-linux-muslStatically linked Debian packagelink
x86_64-unknown-linux-muslStatically linked binarylink
aarch64-unknown-linux-muslStatically linked binarylink
x86_64-unknown-linux-gnuOCI imagelink
aarch64-unknown-linux-muslOCI imagelink
$ sudo wget -O /usr/local/bin/matrix-conduit <url>
$ sudo chmod +x /usr/local/bin/matrix-conduit

Alternatively, you may compile the binary yourself. First, install any dependencies:

# Debian
$ sudo apt install libclang-dev build-essential

$ sudo dnf install clang

Then, cd into the source tree of conduit-next and run:

$ cargo build --release

Adding a Conduit user

While Conduit can run as any user it is usually better to use dedicated users for different services. This also allows you to make sure that the file permissions are correctly set up.

In Debian or RHEL, you can use this command to create a Conduit user:

sudo adduser --system conduit --group --disabled-login --no-create-home

Forwarding ports in the firewall or the router

Conduit uses the ports 443 and 8448 both of which need to be open in the firewall.

If Conduit runs behind a router or in a container and has a different public IP address than the host system these public ports need to be forwarded directly or indirectly to the port mentioned in the config.

Optional: Avoid port 8448

If Conduit runs behind Cloudflare reverse proxy, which doesn't support port 8448 on free plans, delegation can be set up to have federation traffic routed to port 443:

# .well-known delegation on Apache
<Files "/.well-known/matrix/server">
    ErrorDocument 200 '{"m.server": ""}'
    Header always set Content-Type application/json
    Header always set Access-Control-Allow-Origin *

SRV DNS record delegation is also possible.

Setting up a systemd service

Now we'll set up a systemd service for Conduit, so it's easy to start/stop Conduit and set it to autostart when your server reboots. Simply paste the default systemd service you can find below into /etc/systemd/system/conduit.service.

Description=Conduit Matrix Server



Finally, run

$ sudo systemctl daemon-reload

Creating the Conduit configuration file

Now we need to create the Conduit's config file in /etc/matrix-conduit/conduit.toml. Paste in the contents of conduit-example.toml and take a moment to read it. You need to change at least the server name. You can also choose to use a different database backend, but right now only rocksdb and sqlite are recommended.

Setting the correct file permissions

As we are using a Conduit specific user we need to allow it to read the config. To do that you can run this command on Debian or RHEL:

sudo chown -R root:root /etc/matrix-conduit
sudo chmod 755 /etc/matrix-conduit

If you use the default database path you also need to run this:

sudo mkdir -p /var/lib/matrix-conduit/
sudo chown -R conduit:conduit /var/lib/matrix-conduit/
sudo chmod 700 /var/lib/matrix-conduit/

Setting up the Reverse Proxy

This depends on whether you use Apache, Caddy, Nginx or another web server.


Create /etc/apache2/sites-enabled/050-conduit.conf and copy-and-paste this:

# Requires mod_proxy and mod_proxy_http
# On Apache instance compiled from source,
# paste into httpd-ssl.conf or httpd.conf

Listen 8448

<VirtualHost *:443 *:8448>

ServerName # EDIT THIS

AllowEncodedSlashes NoDecode
ProxyPass /_matrix/ timeout=300 nocanon
ProxyPassReverse /_matrix/


You need to make some edits again. When you are done, run

# Debian
$ sudo systemctl reload apache2

# Installed from source
$ sudo apachectl -k graceful


Create /etc/caddy/conf.d/conduit_caddyfile and enter this (substitute for your server name)., {
        reverse_proxy /_matrix/*

That's it! Just start or enable the service and you're set.

$ sudo systemctl enable caddy


If you use Nginx and not Apache, add the following server section inside the http section of /etc/nginx/nginx.conf

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    listen 8448 ssl http2;
    listen [::]:8448 ssl http2;
    server_name; # EDIT THIS
    merge_slashes off;

    # Nginx defaults to only allow 1MB uploads
    # Increase this to allow posting large files such as videos
    client_max_body_size 20M;

    location /_matrix/ {
        proxy_set_header Host $http_host;
        proxy_buffering off;
        proxy_read_timeout 5m;

    ssl_certificate /etc/letsencrypt/live/; # EDIT THIS
    ssl_certificate_key /etc/letsencrypt/live/; # EDIT THIS
    ssl_trusted_certificate /etc/letsencrypt/live/; # EDIT THIS
    include /etc/letsencrypt/options-ssl-nginx.conf;

You need to make some edits again. When you are done, run

$ sudo systemctl reload nginx

SSL Certificate

If you chose Caddy as your web proxy SSL certificates are handled automatically and you can skip this step.

The easiest way to get an SSL certificate, if you don't have one already, is to install certbot and run this:

# To use ECC for the private key, 
# paste into /etc/letsencrypt/cli.ini:
# key-type = ecdsa
# elliptic-curve = secp384r1

$ sudo certbot -d

Automated renewal is usually preconfigured.

If using Cloudflare, configure instead the edge and origin certificates in dashboard. In case you’re already running a website on the same Apache server, you can just copy-and-paste the SSL configuration from your main virtual host on port 443 into the above-mentioned vhost.

You're done!

Now you can start Conduit with:

$ sudo systemctl start conduit

Set it to start automatically when your system boots with:

$ sudo systemctl enable conduit

How do I know it works?

You can open a Matrix client, enter your homeserver and try to register. If you are using a registration token, use Element web, Nheko or SchildiChat web, as they support this feature.

You can also use these commands as a quick health check.

$ curl

# If using port 8448
$ curl
  • To check if your server can talk with other homeservers, you can use the Matrix Federation Tester. If you can register but cannot join federated rooms check your config again and also check if the port 8448 is open and forwarded correctly.

What's next?

Audio/Video calls

For Audio/Video call functionality see the TURN Guide.


If you want to set up an appservice, take a look at the Appservice Guide.

Conduit for Debian


Information about downloading, building and deploying the Debian package, see the "Installing Conduit" section in the Deploying docs. All following sections until "Setting up the Reverse Proxy" be ignored because this is handled automatically by the packaging.


When installed, Debconf generates the configuration of the homeserver (host)name, the address and port it listens on. This configuration ends up in /etc/matrix-conduit/conduit.toml.

You can tweak more detailed settings by uncommenting and setting the variables in /etc/matrix-conduit/conduit.toml. This involves settings such as the maximum file size for download/upload, enabling federation, etc.


The package uses the matrix-conduit.service systemd unit file to start and stop Conduit. It loads the configuration file mentioned above to set up the environment before running the server.

This package assumes by default that Conduit will be placed behind a reverse proxy such as Apache or nginx. This default deployment entails just listening on and the free port 6167 and is reachable via a client using the URL http://localhost:6167.

At a later stage this packaging may support also setting up TLS and running stand-alone. In this case, however, you need to set up some certificates and renewal, for it to work properly.

Conduit for Docker

Note: To run and use Conduit you should probably use it with a Domain or Subdomain behind a reverse proxy (like Nginx, Traefik, Apache, ...) with a Lets Encrypt certificate.


To run Conduit with Docker you can either build the image yourself or pull it from a registry.

Use a registry

OCI images for Conduit are available in the registries listed below. We recommend using the image tagged as latest from GitLab's own registry.

GitLab SizeStable image.
Docker SizeStable image.
GitLab SizeDevelopment version.
Docker SizeDevelopment version.


docker image pull <link>

to pull it to your machine.

Build using a dockerfile

The Dockerfile provided by Conduit has two stages, each of which creates an image.

  1. Builder: Builds the binary from local context or by cloning a git revision from the official repository.
  2. Runner: Copies the built binary from Builder and sets up the runtime environment, like creating a volume to persist the database and applying the correct permissions.

To build the image you can use the following command

docker build --tag matrixconduit/matrix-conduit:latest .

which also will tag the resulting image as matrixconduit/matrix-conduit:latest.


When you have the image you can simply run it with

docker run -d -p 8448:6167 \
  -v db:/var/lib/matrix-conduit/ \
  -e CONDUIT_MAX_REQUEST_SIZE="20000000" \
  -e CONDUIT_PORT="6167" \
  --name conduit <link>

or you can use docker compose.

The -d flag lets the container run in detached mode. You now need to supply a conduit.toml config file, an example can be found here. You can pass in different env vars to change config values on the fly. You can even configure Conduit completely by using env vars, but for that you need to pass -e CONDUIT_CONFIG="" into your container. For an overview of possible values, please take a look at the docker-compose.yml file.

If you just want to test Conduit for a short time, you can use the --rm flag, which will clean up everything related to your container after you stop it.

Docker compose

If the docker run command is not for you or your setup, you can also use one of the provided docker compose files.

Depending on your proxy setup, you can use one of the following files;

When picking the traefik-related compose file, rename it so it matches docker-compose.yml, and rename the override file to docker-compose.override.yml. Edit the latter with the values you want for your server. Additional info about deploying Conduit can be found here.


To build the Conduit image with docker compose, you first need to open and modify the docker-compose.yml file. There you need to comment the image: option and uncomment the build: option. Then call docker compose with:

docker compose up

This will also start the container right afterwards, so if want it to run in detached mode, you also should use the -d flag.


If you already have built the image or want to use one from the registries, you can just start the container and everything else in the compose file in detached mode with:

docker compose up -d

Note: Don't forget to modify and adjust the compose file to your needs.

Use Traefik as Proxy

As a container user, you probably know about Traefik. It is a easy to use reverse proxy for making containerized app and services available through the web. With the two provided files, docker-compose.for-traefik.yml (or docker-compose.with-traefik.yml) and docker-compose.override.yml, it is equally easy to deploy and use Conduit, with a little caveat. If you already took a look at the files, then you should have seen the well-known service, and that is the little caveat. Traefik is simply a proxy and loadbalancer and is not able to serve any kind of content, but for Conduit to federate, we need to either expose ports 443 and 8448 or serve two endpoints .well-known/matrix/client and .well-known/matrix/server.

With the service well-known we use a single nginx container that will serve those two files.

So...step by step:

  1. Copy docker-compose.for-traefik.yml (or docker-compose.with-traefik.yml) and docker-compose.override.yml from the repository and remove .for-traefik (or .with-traefik) from the filename.

  2. Open both files and modify/adjust them to your needs. Meaning, change the CONDUIT_SERVER_NAME and the volume host mappings according to your needs.

  3. Create the conduit.toml config file, an example can be found here, or set CONDUIT_CONFIG="" and configure Conduit per env vars.

  4. Uncomment the element-web service if you want to host your own Element Web Client and create a element_config.json.

  5. Create the files needed by the well-known service.

    • ./nginx/matrix.conf (relative to the compose file, you can change this, but then also need to change the volume mapping)

      server {
          server_name <SUBDOMAIN>.<DOMAIN>;
          listen      80 default_server;
          location /.well-known/matrix/server {
             return 200 '{"m.server": "<SUBDOMAIN>.<DOMAIN>:443"}';
             types { } default_type "application/json; charset=utf-8";
         location /.well-known/matrix/client {
             return 200 '{"m.homeserver": {"base_url": "https://<SUBDOMAIN>.<DOMAIN>"}}';
             types { } default_type "application/json; charset=utf-8";
             add_header "Access-Control-Allow-Origin" *;
         location / {
             return 404;
  6. Run docker compose up -d

  7. Connect to your homeserver with your preferred client and create a user. You should do this immediately after starting Conduit, because the first created user is the admin.

Voice communication

In order to make or receive calls, a TURN server is required. Conduit suggests using Coturn for this purpose, which is also available as a Docker image. Before proceeding with the software installation, it is essential to have the necessary configurations in place.


Create a configuration file called coturn.conf containing:

static-auth-secret=<a secret key>
realm=<your server domain>

A common way to generate a suitable alphanumeric secret key is by using pwgen -s 64 1.

These same values need to be set in conduit. You can either modify conduit.toml to include these lines:

turn_uris = ["turn:<your server domain>?transport=udp", "turn:<your server domain>?transport=tcp"]
turn_secret = "<secret key from coturn configuration>"

or append the following to the docker environment variables dependig on which configuration method you used earlier:

CONDUIT_TURN_URIS: '["turn:<your server domain>?transport=udp", "turn:<your server domain>?transport=tcp"]'
CONDUIT_TURN_SECRET: "<secret key from coturn configuration>"

Restart Conduit to apply these changes.


Run the Coturn image using

docker run -d --network=host -v $(pwd)/coturn.conf:/etc/coturn/turnserver.conf coturn/coturn

or docker compose. For the latter, paste the following section into a file called docker-compose.yml and run docker compose up -d in the same directory.

version: 3
      container_name: coturn-server
      restart: unless-stopped
      network_mode: "host"
        - ./coturn.conf:/etc/coturn/turnserver.conf

To understand why the host networking mode is used and explore alternative configuration options, please visit the following link: For security recommendations see Synapse's Coturn documentation.

Conduit for NixOS

Conduit can be acquired by Nix from various places:

  • The flake.nix at the root of the repo
  • The default.nix at the root of the repo
  • From Nixpkgs

The flake.nix and default.nix do not (currently) provide a NixOS module, so (for now) services.matrix-conduit from Nixpkgs should be used to configure Conduit.

If you want to run the latest code, you should get Conduit from the flake.nix or default.nix and set services.matrix-conduit.package appropriately.

Setting up TURN/STUN

General instructions

Edit/Add a few settings to your existing conduit.toml

# Refer to your Coturn settings. 
# `your.turn.url` has to match the REALM setting of your Coturn as well as `transport`.
turn_uris = ["turn:your.turn.url?transport=udp", "turn:your.turn.url?transport=tcp"]

# static-auth-secret of your turnserver
turn_secret = "ADD SECRET HERE"

# If you have your TURN server configured to use a username and password
# you can provide these information too. In this case comment out `turn_secret above`!
#turn_username = ""
#turn_password = ""

Apply settings

Restart Conduit.

Setting up Appservices

Getting help

If you run into any problems while setting up an Appservice, write an email to, ask us in or open an issue on GitLab.

Set up the appservice - general instructions

Follow whatever instructions are given by the appservice. This usually includes downloading, changing its config (setting domain, homeserver url, port etc.) and later starting it.

At some point the appservice guide should ask you to add a registration yaml file to the homeserver. In Synapse you would do this by adding the path to the homeserver.yaml, but in Conduit you can do this from within Matrix:

First, go into the #admins room of your homeserver. The first person that registered on the homeserver automatically joins it. Then send a message into the room like this: register-appservice

You can confirm it worked by sending a message like this: list-appservices

The @conduit bot should answer with Appservices (1): your-bridge

Then you are done. Conduit will send messages to the appservices and the appservice can send requests to the homeserver. You don't need to restart Conduit, but if it doesn't work, restarting while the appservice is running could help.

Appservice-specific instructions

Remove an appservice

To remove an appservice go to your admin room and execute unregister-appservice <name>

where <name> one of the output of list-appservices.

Tested appservices

These appservices have been tested and work with Conduit without any extra steps:


Here are some of the most frequently asked questions about Conduit, and their answers.

Why do I get a M_INCOMPATIBLE_ROOM_VERSION error when trying to join some rooms?

Conduit doesn't support room versions 1 and 2 at all, and doesn't properly support versions 3-5 currently. You can track the progress of adding support here.

How do I backup my server?

To backup your Conduit server, it's very easy. You can simply stop Conduit, make a copy or file system snapshot of the database directory, then start Conduit again.

Note: When using a file system snapshot, it is not required that you stop the server, but it is still recommended as it is the safest option and should ensure your database is not left in an inconsistent state.

How do I setup sliding sync?

If you use the automatic method for delegation or just proxy .well-known/matrix/client to Conduit, sliding sync should work with no extra configuration. If you don't, continue below.

You need to add a org.matrix.msc3575.proxy field to your .well-known/matrix/client response which contains a url which Conduit is accessible behind. Here is an example:

  "m.homeserver": {
    "base_url": ""
  "org.matrix.msc3575.proxy": {
    "url": ""

Can I migrate from Synapse to Conduit?

Not really. You can reuse the domain of your current server with Conduit, but you will not be able to migrate accounts automatically. Rooms that were federated can be re-joined via the other participating servers, however media and the like may be deleted from remote servers after some time, and hence might not be recoverable.

How do I make someone an admin?

Simply invite them to the admin room. Once joined, they can administer the server by interacting with the @conduit:<server_name> user.