Skip to content

Troubleshooting

Chris & Mike edited this page Mar 23, 2026 · 17 revisions

Troubleshooting

Common issues and solutions when using postgres-mcp.


Understanding Error Responses

Every postgres-mcp tool returns a structured response — never a raw exception. This makes errors deterministic and parseable for both humans and AI agents.

Success Response

{
  "success": true,
  "data": "..."
}

Error Response

{
  "success": false,
  "error": "Table 'public.nonexistent' not found",
  "code": "TABLE_NOT_FOUND",
  "category": "RESOURCE",
  "suggestion": "Check table name spelling or run pg_list_tables",
  "recoverable": true
}

What This Means

  • No raw exceptions — You will never see an unstructured MCP error from a tool call
  • No silent failures — Empty results for nonexistent objects return explicit errors instead of {count: 0}
  • Actionable context — Error messages include the object name, schema, and often a suggestion field
  • Consistent contract — The same {success, error, code, category, suggestion, recoverable} shape across all 248 tools

Connection Issues

Cannot Connect to PostgreSQL

Symptoms:

  • "Connection refused" errors
  • Timeout on database connection

Solutions:

  1. Verify PostgreSQL is running:

    psql -h localhost -U your_user -d your_database
  2. Check connection string format:

    postgres://user:password@host:5432/database
  3. Docker users: Use host.docker.internal instead of localhost:

    {
      "env": {
        "POSTGRES_HOST": "host.docker.internal"
      }
    }
  4. Check firewall rules: Ensure port 5432 is accessible.

  5. Check pg_hba.conf: Ensure your host is allowed to connect.


Cloud Provider Connection Failures

AWS RDS:

  • Use the full endpoint: your-instance.xxxx.us-east-1.rds.amazonaws.com
  • Ensure security group allows inbound traffic on port 5432

Supabase:

  • Use pooler connection string for best performance
  • Enable SSL: ?sslmode=require

Neon:

  • Use the full endpoint with project ID
  • SSL is required: ?sslmode=require

Tool Filtering Issues

"Too many tools" Error

Symptoms:

  • IDE shows tool limit warning
  • Some tools not appearing

Solutions:

Use a restrictive preset:

# Most restrictive general-purpose preset
--tool-filter essential   # 48 tools

# Or extension-only
--tool-filter ext-ai      # 26 tools

See Tool-Filtering for all options.


Extension Tools Not Working

Symptoms:

  • Extension tools return "extension not found"
  • Tools fail with permission errors

Solutions:

  1. Verify extension is installed:

    SELECT * FROM pg_extension WHERE extname = 'pgvector';
  2. Install missing extension:

    CREATE EXTENSION IF NOT EXISTS vector;
  3. Check for shared_preload_libraries (pg_cron, pg_stat_kcache):

    • Edit postgresql.conf
    • Add: shared_preload_libraries = 'pg_cron'
    • Restart PostgreSQL

OAuth Issues

Token Validation Failures

Symptoms:

  • "Invalid token" errors
  • 401 Unauthorized responses

Solutions:

  1. Check token expiration: Tokens may have expired.

  2. Verify audience claim:

    • Token must contain the correct aud claim
    • Keycloak: Add Audience mapper to client
  3. Check issuer URL:

    • Must exactly match OAUTH_ISSUER
    • Include trailing / if your provider requires it
  4. Clock skew: Increase tolerance:

    OAUTH_CLOCK_TOLERANCE=60

Missing Scopes

Symptoms:

  • "Insufficient scope" errors
  • Code Mode "admin required" errors

Solutions:

  1. Request appropriate scopes during token acquisition
  2. Configure client scopes in your OAuth provider
  3. For Code Mode, ensure token has admin scope

Code Mode Issues

Rate Limit Exceeded

Symptoms:

  • "Rate limit exceeded" error after many executions

Solutions:

  • Wait 1 minute for rate limit reset (60 executions/minute)
  • Batch multiple operations into single Code Mode calls
  • Use individual tools for infrequent operations

Code Execution Errors

Symptoms:

  • Code Mode returns execution errors
  • JavaScript syntax errors

Solutions:

  1. Check syntax: Use async/await properly

    // Correct
    const result = await pg.query("SELECT 1");
    return result.rows;
    
    // Incorrect - missing await
    const result = pg.query("SELECT 1");
  2. Avoid blocked operations:

    • No require()
    • No process access
    • No eval()
    • No filesystem or network access
  3. Return a value: Code must return something

    // Always return a value
    return { success: true, data: rows };

Performance Issues

Slow Queries

Solutions:

  1. Check query plan:

    Use pg_explain tool with ANALYZE option
  2. Add missing indexes:

    • Check postgres://indexes resource for unused index warnings
    • Use pg_index_recommendations for suggestions
  3. Update statistics:

    ANALYZE table_name;
  4. Increase cache TTL for stable schemas:

    METADATA_CACHE_TTL_MS=300000  # 5 minutes

Connection Pool Exhaustion

Symptoms:

  • "Connection pool exhausted" errors
  • Timeouts waiting for connections

Solutions:

  1. Check pool status:

    • Read postgres://pool resource
  2. Close long-running transactions:

    • Check postgres://activity for long queries
    • Use pg_cancel_backend if needed
  3. Increase pool size (if available connections exist)


Logging and Debugging

Enable Debug Logging

LOG_LEVEL=debug

This reveals:

  • Connection attempts
  • Query execution details
  • OAuth validation steps
  • Tool resolution

Check Server Status

# Test CLI
node dist/cli.js info
node dist/cli.js list-tools

# Health endpoint (HTTP mode)
curl http://localhost:3000/health

HTTP Transport Issues

SSE Connection Not Initializing

Symptoms:

  • Legacy SSE client connects but never receives tools
  • Python mcp.client.sse hangs after connecting

Solutions:

  1. Verify the server is running with HTTP transport:

    node dist/cli.js --transport http --port 3000
  2. Use the correct endpoint: Legacy SSE clients should connect to /sse, not /mcp:

    # Correct
    async with sse_client("http://localhost:3000/sse") as (read, write):
    
    # Incorrect — /mcp uses Streamable HTTP protocol
    async with sse_client("http://localhost:3000/mcp") as (read, write):
  3. Check health endpoint: curl http://localhost:3000/health


"Parse error: Invalid JSON" on Streamable HTTP

Symptoms:

  • POST /mcp initialize works, but subsequent requests return 400
  • Response: {"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error: Invalid JSON"}}

Solutions:

  1. Include the session header on all requests after initialize:

    -H "Mcp-Session-Id: <id-from-initialize-response>"
  2. Send valid JSON-RPC body — even notifications need a proper body:

    { "jsonrpc": "2.0", "method": "notifications/initialized" }

Session ID Not Found

Symptoms:

  • 404 on POST /messages?sessionId=...
  • 400 on POST /mcp with Mcp-Session-Id header

Solutions:

  1. Session may have expired — SSE sessions close when the client disconnects
  2. Re-initialize — Create a new session by connecting to GET /sse or POST /mcp without a session header
  3. Check server logs — Enable LOG_LEVEL=debug to see session lifecycle events

See HTTP-Transport for full endpoint documentation.


Getting Help

If you're still stuck:

  1. Search the Wiki: AI-Powered Wiki Search
  2. Check GitHub Issues: Open Issues
  3. File a Bug Report: Include logs with LOG_LEVEL=debug

Related

Clone this wiki locally