> ## Documentation Index
> Fetch the complete documentation index at: https://docs.peacock.support/llms.txt
> Use this file to discover all available pages before exploring further.

# Fix Zoom access token errors and auto-refresh failures

> Diagnose and fix common Zoom access token problems, including missing tokens, expiration errors, failed refreshes, and auto-refresh loops.

Zoom Server-to-Server OAuth tokens expire after approximately one hour. The Zoom MCP Server handles most token lifecycle events automatically, but you may occasionally see errors that require manual intervention. This page walks you through each error message and the steps to resolve it.

<AccordionGroup>
  <Accordion title="ZOOM_ACCESS_TOKEN not found in .env file">
    **Error message:**

    ```
    ❌ MISSING: ZOOM_ACCESS_TOKEN not found in .env file
    ```

    Your `.env` file either doesn't exist or doesn't contain a `ZOOM_ACCESS_TOKEN` entry. Fetch a new token to populate it:

    <Steps>
      <Step title="Verify your .env file exists">
        Check that `.env` is present in the project root and contains your Zoom OAuth credentials:

        ```bash theme={null}
        ls -l .env
        ```

        If the file is missing, copy the example and fill in your credentials:

        ```bash theme={null}
        cp .env.example .env
        ```
      </Step>

      <Step title="Fetch a new token">
        Run the token fetch script. It checks for an existing valid token first and only calls the Zoom API if needed:

        ```bash theme={null}
        ./scripts/get_zoom_token.sh
        ```
      </Step>
    </Steps>
  </Accordion>

  <Accordion title="Token expired">
    **Error message:**

    ```
    ⏰ EXPIRED: Token expired at [time]
    ```

    Your token has passed its expiration time. Fetch a fresh one:

    ```bash theme={null}
    ./scripts/get_zoom_token.sh
    ```

    The script checks the existing token before making an API call, so it will only request a new one if the current token is actually expired or missing.
  </Accordion>

  <Accordion title="Token expires too quickly">
    Zoom Server-to-Server OAuth tokens are valid for approximately one hour. The MCP server monitors expiration in the background and automatically refreshes the token when it has less than 5 minutes remaining — no action is required on your part.

    If you need to manage the token manually, use these commands:

    | Command                          | Behavior                                                                 |
    | -------------------------------- | ------------------------------------------------------------------------ |
    | `./scripts/get_zoom_token.sh`    | Smart fetch — only requests a new token if the current one is expired    |
    | `./scripts/get_zoom_token.sh -f` | Force fetch — always requests a new token regardless of current validity |
    | `./run.sh -f`                    | Force fetch a new token, then start the server                           |

    <Tip>
      Adjust how early the server triggers an automatic refresh by setting `ZOOM_AUTO_REFRESH_THRESHOLD` in your `.env` file. The value is in seconds; the default is `300` (5 minutes).
    </Tip>
  </Accordion>

  <Accordion title="Token not updating in .env">
    If the token fetch appears to succeed but the new token isn't reflected in your `.env` file, check the following:

    **Verify the token was written** (the character count should be greater than 600):

    ```bash theme={null}
    grep ZOOM_ACCESS_TOKEN .env | wc -c
    ```

    **Check file permissions** to ensure the script can write to `.env`:

    ```bash theme={null}
    ls -l .env
    ```

    <Note>
      If you see partial writes or the token appears truncated, ensure the project directory is writable and not locked by a sync service. Check file permissions with `ls -l .env`.
    </Note>
  </Accordion>

  <Accordion title="Token validation fails after refresh">
    **Symptom:** Running `check_zoom_token.sh` reports the token as expired immediately after you fetched a new one.

    This usually means your shell environment still holds the old token value. Reload the environment and re-run the check:

    ```bash theme={null}
    source .env && ./scripts/check_zoom_token.sh
    ```

    You can also verify the token length directly in the file:

    ```bash theme={null}
    grep ZOOM_ACCESS_TOKEN .env | grep -o 'ey[A-Za-z0-9]*' | wc -c
    ```

    The character count should be greater than 100. A shorter result indicates the token is malformed or truncated.
  </Accordion>

  <Accordion title="Stuck in auto-refresh loop">
    The server has built-in protection against refresh loops: it enforces a 30-second cooldown between attempts and disables auto-refresh after 3 consecutive failures. When auto-refresh is disabled, you'll see this message in the terminal:

    ```
    CRITICAL: Max refresh failures reached. Auto-refresh disabled.
    ```

    To recover manually, force a new token and update the Claude Desktop config in one step:

    ```bash theme={null}
    ./scripts/get_zoom_token.sh -f && bash scripts/update_claude_config.sh
    ```

    After running this command, restart Claude Desktop so it picks up the new token.
  </Accordion>

  <Accordion title="python3 not found">
    The token validation scripts use Python 3 to parse the JWT expiration claim. If `python3` is not available on your system, the scripts fall back to a token refresh for safety, but you'll see an error.

    Install Python 3 via Homebrew on macOS:

    ```bash theme={null}
    brew install python3
    ```

    Alternatively, install `jq` for JSON parsing:

    ```bash theme={null}
    brew install jq
    ```

    Verify the installation:

    ```bash theme={null}
    python3 --version
    ```
  </Accordion>
</AccordionGroup>
