Matomo Troubleshooting & Debugging | OpsBlu Docs

Matomo Troubleshooting & Debugging

Diagnose and fix common Matomo tracking issues. Covers script loading failures, missing events, data discrepancies, integration conflicts, and.

Overview

This guide helps you diagnose and resolve common Matomo (formerly Piwik) tracking issues. Matomo provides privacy-focused analytics with full data ownership, making proper configuration essential.

Debug Mode

Enable JavaScript Tracker Debugging

Enable debug mode to see detailed tracking information:

// Enable debug mode
_paq.push(['enableDebug']);

// Or configure Matomo object directly
var _paq = window._paq = window._paq || [];
_paq.push(['enableDebug']);
_paq.push(['trackPageView']);

Check Matomo Loading

Verify Matomo is loaded correctly:

// Check if Matomo tracker exists
if (typeof _paq !== 'undefined') {
  console.log('Matomo tracker loaded');
  console.log('_paq queue:', _paq);
} else {
  console.error('Matomo tracker not loaded');
}

// Check Matomo object
if (typeof Matomo !== 'undefined') {
  console.log('Matomo object loaded');
  console.log('Trackers:', Matomo.getAsyncTrackers());
} else {
  console.log('Matomo object not yet loaded (may load async)');
}

Common Issues

No Data in Reports

Symptoms: Tracking code installed but no data appears in Matomo.

Solutions:

  1. Verify tracking code installation:
<!-- Matomo tracking code should be before </head> or </body> -->
<script>
  var _paq = window._paq = window._paq || [];
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);
  (function() {
    var u="//matomo.example.com/";
    _paq.push(['setTrackerUrl', u+'matomo.php']);
    _paq.push(['setSiteId', '1']);
    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
    g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
  })();
</script>
  1. Check Site ID:
// Verify Site ID is correct
_paq.push(['setSiteId', '1']);  // Should match your Matomo site ID

// Log current tracker configuration
_paq.push([function() {
  var tracker = this;
  console.log('Tracker URL:', tracker.getTrackerUrl());
  console.log('Site ID:', tracker.getSiteId());
}]);
  1. Verify Matomo server URL:
// Check tracker URL points to your Matomo installation
_paq.push(['setTrackerUrl', 'https://matomo.example.com/matomo.php']);

// Test if matomo.php is accessible
// Visit: https://matomo.example.com/matomo.php
// Should return: GIF89a (1x1 tracking pixel)
  1. Check network requests:

    • Open DevTools → Network tab
    • Filter by "matomo"
    • Look for requests to matomo.php
    • Status should be 200 or 204
    • Response should be 1x1 GIF or empty
  2. Verify archiving is working:

    • For self-hosted Matomo, ensure cron job is running
    • Check System → General Settings → Archive Reports
    • Configure auto-archiving if not already set

Events Not Tracking

Symptoms: Custom events aren't appearing in Matomo.

Solutions:

  1. Verify event tracking syntax:
// Track event
_paq.push(['trackEvent', 'Category', 'Action', 'Name', Value]);

// Examples:
_paq.push(['trackEvent', 'Videos', 'Play', 'Product Demo']);
_paq.push(['trackEvent', 'Downloads', 'PDF', 'Whitepaper', 1]);
_paq.push(['trackEvent', 'Engagement', 'Button Click', 'Signup']);
  1. Check event appears in reports:

    • Go to Behavior → Events
    • May take a few minutes to appear
    • Check correct date range
  2. Enable debug mode to verify:

_paq.push(['enableDebug']);
_paq.push(['trackEvent', 'Test', 'Click', 'Debug Test']);
// Check browser console for tracking details
  1. Verify _paq is loaded before tracking:
// Wait for _paq to be ready
function trackMatomoEvent(category, action, name, value) {
  if (typeof _paq !== 'undefined') {
    _paq.push(['trackEvent', category, action, name, value]);
  } else {
    console.error('Matomo not loaded - event not tracked');
  }
}

trackMatomoEvent('Button', 'Click', 'CTA');

Goals Not Recording

Symptoms: Goal conversions not showing in reports.

Solutions:

  1. Verify goal is defined:

    • Go to Administration → Websites → Manage Goals
    • Check goal is active
    • Verify goal conditions are correct
  2. Track manual goal conversion:

// Trigger goal conversion manually
_paq.push(['trackGoal', 1]);  // Goal ID 1

// With revenue
_paq.push(['trackGoal', 1, 99.99]);

// Verify in console with debug mode
_paq.push(['enableDebug']);
_paq.push(['trackGoal', 1]);
  1. Check goal matching:

    • For URL-based goals, verify pattern matches
    • Test URL patterns in goal configuration
    • Check case sensitivity
  2. Verify timing:

    • Goals appear within minutes
    • Check correct date range in reports

Ecommerce Tracking Not Working

Symptoms: Ecommerce data not appearing.

Solutions:

  1. Enable ecommerce in Matomo:

    • Go to Administration → Websites → Manage
    • Enable "Ecommerce" for the website
  2. Track ecommerce order:

// Add product to cart
_paq.push(['addEcommerceItem',
  'SKU123',           // Product SKU
  'Product Name',     // Product name
  'Category',         // Product category
  99.99,              // Price
  1                   // Quantity
]);

// Track ecommerce order
_paq.push(['trackEcommerceOrder',
  'ORDER-123',        // Order ID (required, unique)
  109.99,             // Grand Total
  99.99,              // Sub total
  8.00,               // Tax
  5.00,               // Shipping
  false               // Discount
]);
  1. Track cart update:
// Track abandoned cart
_paq.push(['addEcommerceItem', 'SKU123', 'Product', 'Category', 99.99, 1]);
_paq.push(['trackEcommerceCartUpdate', 99.99]);
  1. Verify in reports:
    • Go to Ecommerce → Overview
    • Check Orders, Revenue tabs
    • May take a few minutes to appear

User ID Not Working

Symptoms: User ID not being set or tracked.

Solutions:

  1. Set User ID:
// Set User ID before trackPageView
_paq.push(['setUserId', 'user@example.com']);
_paq.push(['trackPageView']);

// Verify it's set
_paq.push([function() {
  console.log('User ID:', this.getUserId());
}]);
  1. Reset User ID:
// Reset User ID (e.g., on logout)
_paq.push(['resetUserId']);
_paq.push(['trackPageView']);
  1. Enable User ID reporting:
    • Go to Administration → Privacy → Users opt-out
    • Configure User ID settings

Cross-Domain Tracking Issues

Symptoms: Sessions breaking across domains.

Solutions:

  1. Configure cross-domain linking:
// Enable cross-domain linking
_paq.push(['enableCrossDomainLinking']);

// Set domains to track
_paq.push(['setDomains', ['*.example.com', '*.example.org']]);
  1. Verify link decoration:
// Links to other domains should have pk_vid parameter
// Example: https://example.org/page?pk_vid=...

// Test cross-domain tracking
_paq.push(['enableDebug']);
// Click link to other domain
// Check URL has pk_vid parameter
  1. Whitelist domains:
// Specify which domains to include
_paq.push(['setDomains', [
  '*.example.com',
  'subdomain.example.org',
  'checkout.example.net'
]]);

Debugging Techniques

Comprehensive Health Check

// Complete Matomo diagnostic
function matomoHealthCheck() {
  console.group('Matomo Health Check');

  // 1. Check if _paq exists
  if (typeof _paq === 'undefined') {
    console.error('_paq not defined');
    console.groupEnd();
    return;
  }
  console.log('✓ _paq loaded');

  // 2. Get tracker info
  _paq.push([function() {
    var tracker = this;
    console.log('Tracker URL:', tracker.getTrackerUrl());
    console.log('Site ID:', tracker.getSiteId());
    console.log('User ID:', tracker.getUserId() || 'Not set');
    console.log('Visitor ID:', tracker.getVisitorId());
  }]);

  // 3. Send test page view
  _paq.push(['trackPageView', 'Health Check Test']);
  console.log('✓ Test page view sent');

  console.groupEnd();
}

matomoHealthCheck();

Monitor Tracking Requests

// Log all tracking requests
function monitorMatomoRequests() {
  const observer = new PerformanceObserver((list) => {
    list.getEntries().forEach((entry) => {
      if (entry.name.includes('matomo.php')) {
        console.log('Matomo tracking request:', entry.name);
        console.log('Duration:', entry.duration, 'ms');
      }
    });
  });

  observer.observe({ entryTypes: ['resource'] });
}

monitorMatomoRequests();

Test Custom Dimensions

// Set and verify custom dimensions
_paq.push(['setCustomDimension', 1, 'Value 1']);
_paq.push(['setCustomDimension', 2, 'Value 2']);

// Log custom dimensions
_paq.push([function() {
  var customDimensions = this.getCustomDimension(1);
  console.log('Custom Dimension 1:', customDimensions);
}]);

_paq.push(['trackPageView']);

Browser-Specific Issues

Safari ITP (Intelligent Tracking Prevention)

// Matomo uses first-party cookies, less affected by ITP
// But consider server-side tracking for better persistence

// Set cookie domain explicitly
_paq.push(['setCookieDomain', '*.example.com']);
_paq.push(['setDomains', ['*.example.com']]);

Content Security Policy (CSP)

<!-- Add Matomo domains to CSP -->
<meta http-equiv="Content-Security-Policy"
      content="script-src 'self' https://matomo.example.com 'unsafe-inline';
               img-src 'self' https://matomo.example.com;
               connect-src 'self' https://matomo.example.com;">

Do Not Track (DNT)

// Check if DNT is respected
_paq.push([function() {
  console.log('Respecting DNT:', this.isUserOptedOut());
}]);

// Disable DNT support if needed
_paq.push(['setDoNotTrack', false]);

Self-Hosted Matomo Issues

Archiving Not Running

Symptoms: Reports not updating, old data.

Solutions:

  1. Check cron job:
# Verify cron job is configured
crontab -l | grep matomo

# Should have something like:
# */5 * * * * /usr/bin/php /path/to/matomo/console core:archive --url=https://matomo.example.com
  1. Run manual archiving:
# SSH to server and run
cd /path/to/matomo
php console core:archive --url=https://matomo.example.com
  1. Configure auto-archiving:
    • Go to System → General Settings
    • Under "Archive Reports" set to "Yes"
    • Configure cron to run every 5-15 minutes

Database Performance Issues

// Check if tracking is slow
_paq.push([function() {
  var start = Date.now();
  this.trackPageView();
  var duration = Date.now() - start;
  console.log('Tracking took:', duration, 'ms');

  if (duration > 1000) {
    console.warn('Slow Matomo tracking - check database');
  }
}]);

Memory Limit Errors

# Increase PHP memory limit in php.ini
memory_limit = 256M

# Or in .htaccess
php_value memory_limit 256M

Data Quality Issues

Bot Filtering

// Matomo has built-in bot filtering
// Configure in Settings → Websites → Manage
// Check "Exclude visits based on user agent"

// Additional bot detection
_paq.push([function() {
  if (/bot|crawler|spider/i.test(navigator.userAgent)) {
    console.log('Bot detected - may not track');
  }
}]);

Duplicate Tracking

// Prevent duplicate page views
var pageTracked = false;

function trackPageOnce() {
  if (!pageTracked) {
    _paq.push(['trackPageView']);
    pageTracked = true;
  }
}

trackPageOnce();

GDPR Compliance

// Require consent before tracking
_paq.push(['requireConsent']);

// After user gives consent
_paq.push(['setConsentGiven']);

// Or require cookie consent
_paq.push(['requireCookieConsent']);
_paq.push(['setCookieConsentGiven']);

// Check consent status
_paq.push([function() {
  console.log('Has consent:', this.hasConsent());
}]);

Common Error Messages

Error Message Cause Fix
Matomo cannot connect to the database Database credentials are wrong, MySQL/MariaDB service is stopped, or the socket file is missing Verify database_host, database_username, and database_password in config/config.ini.php. Restart the database service and check that the socket path in my.cnf matches the Matomo config.
GeoIP database not found The MaxMind GeoIP2 .mmdb file is missing or the path in the GeoIP2 plugin settings is incorrect Download a fresh GeoLite2-City database from MaxMind, place it in misc/, and update the path under Administration > System > Geolocation. Ensure the php-maxminddb extension is installed.
Plugin requires Matomo X.Y but current version is X.Z A plugin was built for a newer Matomo release than the one installed Update Matomo to the version the plugin requires, or downgrade the plugin to a version compatible with your installation via the Marketplace.
Unable to write to tmp directory The web server user lacks write permissions on matomo/tmp/ Run chown -R www-data:www-data /path/to/matomo/tmp and chmod -R 0755 /path/to/matomo/tmp. On SELinux systems, also run chcon -R -t httpd_sys_rw_content_t tmp/.
Token authentication failed The token_auth value passed to the API is invalid, revoked, or belongs to a deleted user Generate a new token under Administration > Personal > Security and update all API calls and cron jobs that reference the old token.
No data has been recorded yet The tracking code is not installed, the Site ID is wrong, or the archiving cron has not run Verify the JavaScript snippet is present on the site, confirm the Site ID matches Administration > Websites > Manage, and trigger a manual archive with php console core:archive.
Maximum execution time exceeded PHP max_execution_time is too low for archiving or a large API query Increase max_execution_time to 300 in php.ini or pass --php-cli-options="-d max_execution_time=0" to the archive command.
Archive processing timed out The cron archiver exceeded its internal timeout while processing a site with high traffic volume Add --force-timeout-for-periods=3600 to the cron command. Also consider enabling segment archiving in config.ini.php with [General] enable_browser_archiving_triggering = 0.
Invalid site ID API call or tracking request references a Site ID that does not exist in the Matomo installation Check the correct Site ID in Administration > Websites > Manage. The ID is the integer shown in the first column.
Tracker request rejected: Bot detected Matomo's server-side bot detection flagged the visitor's User-Agent as a known crawler If the traffic is legitimate (e.g., a custom internal tool), add the User-Agent string to the exclusion allowlist under Administration > Websites > Manage > Excluded User Agents.
Failed to write to session directory PHP session save path is unwritable or the disk is full Check session.save_path in php.ini, ensure the directory exists and is writable by the web server user, and verify available disk space with df -h.
SSL certificate verify failed Outbound HTTPS requests from Matomo (e.g., plugin updates, GeoIP downloads) fail because the CA bundle is missing or outdated Update the system CA certificates (update-ca-certificates on Debian/Ubuntu) and set curl.cainfo in php.ini to point to the updated bundle, typically /etc/ssl/certs/ca-certificates.crt.

Getting Help

Check Matomo System Check

For self-hosted Matomo:

  1. Go to Administration → System Check
  2. Review all system requirements
  3. Fix any warnings or errors

Diagnostic Report

// Generate comprehensive diagnostic
function matomoDiagnostics() {
  console.group('Matomo Diagnostics');

  if (typeof _paq === 'undefined') {
    console.error('_paq not loaded');
    console.groupEnd();
    return;
  }

  _paq.push([function() {
    var tracker = this;

    console.log('Configuration:');
    console.log('- Tracker URL:', tracker.getTrackerUrl());
    console.log('- Site ID:', tracker.getSiteId());
    console.log('- Cookie Domain:', tracker.getCookieDomain());

    console.log('\nUser:');
    console.log('- User ID:', tracker.getUserId() || 'Not set');
    console.log('- Visitor ID:', tracker.getVisitorId());

    console.log('\nSettings:');
    console.log('- Link Tracking:', tracker.isLinkTrackingEnabled());
    console.log('- Cookie Enabled:', tracker.isCookieEnabled());
    console.log('- Has Cookies:', tracker.hasCookies());
  }]);

  console.groupEnd();
}

matomoDiagnostics();

Contact Support

  1. Matomo Forums:

  2. Matomo Documentation:

  3. Professional Support:

    • For self-hosted: Matomo On-Premise Support
    • For cloud: Matomo Cloud Support
    • Email: support@matomo.org (paid plans)

Best Practices

Regular Testing

// Create test suite
function runMatomoTests() {
  console.group('Matomo Tests');

  // 1. Test page view
  _paq.push(['trackPageView', 'Test Page']);
  console.log('✓ Page view tracked');

  // 2. Test event
  _paq.push(['trackEvent', 'Test', 'Click', 'Test Event']);
  console.log('✓ Event tracked');

  // 3. Test custom dimension
  _paq.push(['setCustomDimension', 1, 'Test Value']);
  console.log('✓ Custom dimension set');

  // 4. Test user ID
  _paq.push(['setUserId', 'test_user']);
  console.log('✓ User ID set');

  console.groupEnd();
}

runMatomoTests();

Monitor in Production

// Log Matomo errors
window.addEventListener('error', function(e) {
  if (e.message && (e.message.includes('matomo') || e.message.includes('piwik'))) {
    console.error('Matomo error:', e);
    // Send to error tracking service
  }
});

// Monitor Matomo availability
setInterval(function() {
  if (typeof _paq === 'undefined') {
    console.error('Matomo tracker unavailable');
    // Alert monitoring service
  }
}, 60000); // Check every minute

Testing Checklist

  • Matomo script loaded successfully
  • Site ID is correct
  • Tracker URL is correct and accessible
  • Page views tracking
  • Events tracking correctly
  • Goals recording (if configured)
  • Ecommerce tracking (if enabled)
  • User ID being set (if applicable)
  • Custom dimensions working (if used)
  • No console errors
  • Network requests successful
  • Data appearing in reports