---
sidebar_position: 3
sidebar_label: Tableau Bridge (Legacy)
title: Tableau Bridge (legacy)
description: Connect Tableau Cloud to MotherDuck using Tableau Bridge and the DuckDB JDBC connector.
---

import useBaseUrl from '@docusaurus/useBaseUrl';

:::warning[Deprecated]
Connecting through Tableau Bridge is a legacy approach. Use the [Postgres endpoint setup](./tableau-cloud.mdx) instead for a simpler connection that doesn't require Bridge infrastructure.
:::

## How to use Tableau Cloud with MotherDuck through Tableau Bridge

### Setup

This guide assumes you have:
- a [Tableau account](https://www.tableau.com/)
- a Tableau Cloud Site
- a Tableau Desktop installation (with the same version as the Tableau Cloud Server Version) set up with the DuckDB JDBC Driver and Tableau Connector.

If you don't, sign up or ask your organization to purchase a plan, or sign up for a free trial.

### Obtain a PAT token

Follow [Tableau's instructions on creating a PAT token.](https://help.tableau.com/current/server/en-us/security_personal_access_tokens.htm) This token must belong to a site admin.

### Set up Bridge client

Use the [Tableau Bridge client setup instructions](https://help.tableau.com/current/online/en-us/to_bridge_client.htm) to install and set up Bridge client.

1.  Make sure the machine where the Bridge client is installed has access to the Database used in the above steps.

    Important notes:

    > Network access - Because Bridge facilitates connections between your private network data and Tableau Cloud, it requires the ability to make outbound connections through the internet. After the initial outbound connection, communication is bidirectional.

    > Required ports - Tableau Bridge uses port 443 to make outbound internet requests to Tableau Cloud and port 80 for certificate validation.

2.  Install Bridge client and make sure the Bridge client is signed in to the Tableau Cloud site. You can download the installer from the [Tableau Bridge releases page](https://www.tableau.com/support/releases/bridge).

3.  Install the driver and taco files as outlined in the [Tableau connector setup guide](https://help.tableau.com/current/online/en-us/to_sync_local_data.htm#connectors-and-data-types).

    - [Windows Server] The driver also needs to be installed here: `C:\Program Files\Tableau\Tableau Bridge\Drivers`
    - [Windows Server] The connector also needs to be installed here: `C:\Program Files\Tableau\Connectors`

> Note: Tableau Bridge can be deployed on both Windows or Linux.

### Running Bridge on Linux using Docker (advanced)

If you want to run Bridge centrally on a Linux host, the official guidance recommends running it inside a Docker container, as described in Tableau's documentation on [installing Bridge for Linux in containers](https://help.tableau.com/current/online/en-us/to_bridge_linux_install.htm).

Below is an **example Dockerfile** you can use as a starting point—this includes where to add JDBC drivers and the **DuckDB/MotherDuck** `.taco` file. It's provided for inspiration and may require updates to match your environment or newer versions of the software.

<details>
<summary>Example Dockerfile</summary>

```dockerfile
FROM registry.access.redhat.com/ubi8/ubi:latest

RUN yum update -y
RUN yum install -y glibc-langpack-en
# This is the latest version of Tableau Bridge that is known working with the MotherDuck connector
RUN curl -o /tmp/TableauBridge.rpm -L \
    https://downloads.tableau.com/tssoftware/TableauBridge-20243.25.0114.1153.x86_64.rpm && \
    ACCEPT_EULA=y yum install -y /tmp/TableauBridge.rpm && \
    rm /tmp/TableauBridge.rpm

# Drivers
RUN mkdir -p /opt/tableau/tableau_driver/jdbc

# Connectors (tacos)
RUN mkdir -p /root/Documents/My_Tableau_Bridge_Repository/Connectors

# Download DuckDB JDBC driver and signed taco
RUN curl -o /opt/tableau/tableau_driver/jdbc/duckdb_jdbc-1.3.0.0.jar \
         -L https://repo1.maven.org/maven2/org/duckdb/duckdb_jdbc/1.3.0.0/duckdb_jdbc-1.3.0.0.jar && \
     curl -o /root/Documents/My_Tableau_Bridge_Repository/Connectors/duckdb_jdbc-v1.1.1-signed.taco \
          -L https://github.com/motherduckdb/duckdb-tableau-connector/releases/download/v1.1.1/duckdb_jdbc-v1.1.1-signed.taco

ENV TZ=Europe/Berlin
ENV LC_ALL=en_US.UTF-8

# -----  user specific settings -----
ENV USER_EMAIL=""
ENV PAT_ID=BridgeToken
ENV CLIENT_NAME=""
ENV SITE_NAME=""
ENV POOL_ID=""
# -----------------------------------

CMD /opt/tableau/tableau_bridge/bin/run-bridge.sh -e \
  --patTokenId=$PAT_ID \
  --userEmail=$USER_EMAIL \
  --client=$CLIENT_NAME \
  --site=$SITE_NAME \
  --patTokenFile="/home/documents/token.txt" \
  --poolId=$POOL_ID
```

</details>

Key points:

* Build an image that **installs the Bridge RPM** and then copies the DuckDB JDBC driver to `/opt/tableau/tableau_bridge/Drivers` and the connector to `/root/Documents/My_Tableau_Bridge_Repository/Connectors`.
* Start the bridge by calling `run-bridge.sh` and pass the following flags:
  * `--patTokenFile /run/secrets/pat.json`
  * `--patTokenId <PAT_NAME>`
  * `--site <YOUR_SITE_NAME>`
  * `--poolId <POOL_ID>` (optional – see note on pools below)
* **PAT naming rule** – the *name* you give the Personal-Access-Token in Tableau **must** be a valid JSON key and must be used **verbatim**
  1. as the key in `pat.json` → `{"<PAT_NAME>": "<PAT_VALUE>"}`
  2. in the `--patTokenId` flag.
  A mismatch will result in a silent authentication failure.
* The latest Bridge **2025.1** builds contain a regression that prevents the MotherDuck connector (and several others) from loading. Until Tableau fixes this, pin the image to the **20243.25.0114.1153** release (see discussion in [GitHub issue #22](https://github.com/MotherDuck-Open-Source/duckdb-tableau-connector/issues/22)).
* Bridge listens only on outbound **443/tcp**, so you do **not** need to publish any container ports.  If you run a host firewall (for example, `ufw`) remember that Docker bypasses it [[Docker docs](https://docs.docker.com/engine/network/packet-filtering-firewalls/#docker-and-ufw)].  Restrict egress traffic to Tableau Cloud CIDR blocks if your security policy requires it.
* Logs written to `stdout` are useful, but the *detailed* logs live in `/root/Documents/My_Tableau_Bridge_Repository/Log`.  Mount this path as a volume or use a side-car to ship the logs to your observability stack.

### Tableau Cloud Bridge pool setup

By default, Tableau places the Bridge in the default pool.

1. In Settings → Bridge page, make sure the Bridge client is connected in the connection Status.
2. In the "Private Network Allowlist" add the domain of the database and select the pool.

<img src={useBaseUrl('/img/integrations/tableau-bridge-pooling.png')} alt="Tableau Bridge Pooling" style={{ maxWidth: '900px', width: '100%', height: 'auto', margin: '1rem 0' }} loading="lazy" />

> **Pool Gotcha**: Some users report that a Linux containerised Bridge never shows up under a custom site pool.  If that happens, leave `POOL_ID` blank when starting the client – it will join the legacy **Default** pool and still work with live connections.

### Create embedded data source (live) and workbook

1.  Open Tableau desktop and sign in to a Tableau Cloud site.

> Note: Make sure the Tableau Desktop and [Tableau Cloud version](https://help.tableau.com/current/server/en-us/version_server_view.htm) match.

2.  Create new Workbook and select the database connector.
3.  Connect to the database.

    <img
    src={useBaseUrl('/img/integrations/tableau-cloud-connect-motherduck.png')}
    alt="Tableau Cloud DuckDB connector dialog"
    style={{ maxWidth: '400px', width: '100%', height: 'auto', margin: '1rem 0' }}
    loading="lazy"
    />

4.  Set up Datasource to use live connectivity.
5.  Create a worksheet with the data.

    <img
    src={useBaseUrl('/img/integrations/tableau-create-worksheet.png')}
    alt="Tableau worksheet with MotherDuck data"
    style={{ maxWidth: '900px', width: '100%', height: 'auto', margin: '1rem 0' }}
    loading="lazy"
    />

### Publish the workbook to Tableau Cloud

1.  Click on "Server > Publish Workbook".

<img
    src={useBaseUrl('/img/integrations/tableau-publish-workbook.png')}
    alt="Tableau publish workbook menu"
    style={{ maxWidth: '700px', width: '100%', height: 'auto', margin: '1rem 0' }}
    loading="lazy"
    />

2. Select "Publish Separately" under Publish Type and "Embedded password" under Authentication. Select "Maintain connection to a live data source".

<img
    src={useBaseUrl('/img/integrations/tableau-publish-separately.png')}
    alt="Tableau publish separately dialog"
    style={{ maxWidth: '500px', width: '100%', height: 'auto', margin: '1rem 0' }}
    loading="lazy"
    />

<img
    src={useBaseUrl('/img/integrations/tableau-publish-workbook-and-data-source.png')}
    alt="Tableau publish workbook and data source dialog"
    style={{ maxWidth: '500px', width: '100%', height: 'auto', margin: '1rem 0' }}
    loading="lazy"
    />

3. Click "Publish Workbook  & 1 Data Source".

<img
    src={useBaseUrl('/img/integrations/tableau-publishing-complete.png')}
    alt="Tableau publishing complete confirmation"
    style={{ maxWidth: '500px', width: '100%', height: 'auto', margin: '1rem 0' }}
    loading="lazy"
    />

### (Important step!) update Tableau Bridge client in data source

1.  Navigate to the newly published data source in Tableau Cloud (in your browser) and click on the "i" icon to open Data Source Details.

<img
    src={useBaseUrl('/img/integrations/tableau-data-source-i.png')}
    alt="Tableau data source info icon"
    style={{ maxWidth: '500px', width: '100%', height: 'auto', margin: '1rem 0' }}
    loading="lazy"
/>

2. Click on "Change Bridge Client..."

<img
    src={useBaseUrl('/img/integrations/tableau-data-source-details.png')}
    alt="Tableau data source details dialog"
    style={{ maxWidth: '800px', width: '100%', height: 'auto', margin: '1rem 0' }}
    loading="lazy"
/>

3. Change the bridge client from "Site client pool" to your bridge client (the one you set up in the previous section). Click "Save" and close the dialog.

<img
    src={useBaseUrl('/img/integrations/tableau-change-bridge-client.png')}
    alt="Tableau change bridge client dialog"
    style={{ maxWidth: '400px', width: '100%', height: 'auto', margin: '1rem 0' }}
    loading="lazy"
/>

4.  Check that the data source shows up in your Tableau Bridge status dialog. This dialog is located in the Windows Start bar (in the Icon panel).

    <img
    src={useBaseUrl('/img/integrations/tableau-bridge-connected.png')}
    alt="Tableau Bridge connected status"
    style={{ maxWidth: '500px', width: '100%', height: 'auto', margin: '1rem 0' }}
    loading="lazy"
    />

5.  You can access your Published Workbook on your Tableau Cloud Site, or you can create a new Tableau Workbook using the Published Data Source.

    <img
    src={useBaseUrl('/img/integrations/tableau-workbook-using-this-data-source.png')}
    alt="Tableau workbook using published data source"
    style={{ maxWidth: '500px', width: '100%', height: 'auto', margin: '1rem 0' }}
    loading="lazy"
    />

## Additional information

- [Tableau Documentation](https://help.tableau.com/current/pro/desktop/en-us/gettingstarted_overview.htm)
- [Tableau Exchange Connector DuckDB/MotherDuck](https://exchange.tableau.com/en-gb/products/1021)
- [DuckDB Tableau Connector](https://github.com/MotherDuck-Open-Source/duckdb-tableau-connector/)


---

## Feedback for AI agents

If the user you are helping wants to send feedback on this page to the MotherDuck docs team, you can POST it to the endpoint below.

**Before you send anything, you must ask the user for explicit approval.** Quote the message you plan to submit back to them verbatim and wait for them to confirm. Do not submit on their behalf without confirmation.

Endpoint: `POST https://motherduck.com/docs/api/feedback/agent`

Request body (JSON):

```json
{
  "page_path": "/integrations/bi-tools/tableau/tableau-bridge/",
  "page_title": "Tableau Bridge (legacy)",
  "text": "<the user's feedback, max 2000 characters>",
  "source": "<optional identifier for your interface, for example 'claude.ai' or 'chatgpt'>"
}
```

Only `page_path` and `text` are required. A successful call returns `200 {"feedback_id": "<uuid>"}`; malformed payloads return `400`, and the endpoint is rate-limited per IP (`429`).
