Grafana can email PDF exports of dashboards, but it’s often a black box when things go wrong.

The core issue is that Grafana’s reporting feature relies on an external "renderer" service, usually grafana-image-renderer, to actually generate the PDFs. If this service isn’t running, misconfigured, or can’t reach its dependencies, your reports will fail. It’s not Grafana itself that’s failing to send the email, but the generator of the email’s content.

Here’s a breakdown of what to check when your scheduled PDF reports aren’t working:

  1. grafana-image-renderer Service Status: This is the most common culprit. The renderer service needs to be running and accessible by your main Grafana instance.

    • Diagnosis: On the server where you installed grafana-image-renderer, check its status. If you installed it as a systemd service, use sudo systemctl status grafana-image-renderer. Look for "active (running)".
    • Fix: If it’s not running, start it with sudo systemctl start grafana-image-renderer. If you’re running it manually, ensure the process is still alive.
    • Why it works: Grafana sends a request to this separate service over HTTP to render the dashboard. If the service isn’t listening, the request fails.
  2. Grafana Configuration (grafana.ini): Grafana needs to know where to find the renderer service.

    • Diagnosis: Check your Grafana configuration file (usually /etc/grafana/grafana.ini or within your Grafana Docker configuration). Look for the [renderer] section.
    • Fix: Ensure enabled = true and that external_renderer_url points to the correct address and port of your running grafana-image-renderer service. For example, external_renderer_url = http://localhost:8081/render/. If grafana-image-renderer is running in a separate Docker container, this would be its internal IP and port (e.g., http://172.17.0.3:8081/render/). After changing this, restart Grafana: sudo systemctl restart grafana-server.
    • Why it works: This tells Grafana the network endpoint to send rendering requests to. An incorrect URL means Grafana is trying to talk to the wrong place.
  3. Network Connectivity & Firewalls: Grafana needs to be able to reach the renderer service, and vice-versa if there are complex setups.

    • Diagnosis: From the Grafana server, try to curl the renderer’s endpoint: curl http://localhost:8081/render/ (adjusting the URL to match your external_renderer_url). You should get a 200 OK response. If grafana-image-renderer is on a different host or in a different Docker network, test connectivity from the Grafana host to that host/IP.
    • Fix: If curl fails, check firewall rules on both the Grafana server and the renderer server. Ensure the port (e.g., 8081) is open. If using Docker, verify the container networks are configured correctly for communication.
    • Why it works: Network restrictions prevent Grafana from even sending the request to the renderer service.
  4. Renderer Service Dependencies (Headless Browser): The grafana-image-renderer itself relies on a headless browser (usually Chrome or Chromium) to render dashboards. If the browser isn’t installed or configured correctly within the renderer’s environment, rendering will fail.

    • Diagnosis: Check the logs of the grafana-image-renderer service. You’ll often see errors related to failing to launch Chrome or missing browser binaries. If running via Docker, ensure the image has a functional browser.
    • Fix: For Linux installations, install Chromium: sudo apt-get update && sudo apt-get install -y chromium-browser (Debian/Ubuntu) or sudo yum install -y chromium (CentOS/RHEL). Ensure the renderer service is configured to find it (often automatic if installed in standard locations). If using Docker, use an official image that includes a browser, or build one that does.
    • Why it works: The renderer uses the headless browser to load the dashboard HTML, execute JavaScript, and capture the rendered output as an image or PDF. Without it, it can’t perform the rendering.
  5. Authentication/API Keys (Less Common for Internal): If your Grafana is behind a proxy or requires authentication for internal API calls, this could interfere.

    • Diagnosis: Review Grafana logs for errors indicating authentication failures or unauthorized access when trying to communicate with the renderer.
    • Fix: Ensure that no authentication layer is blocking the communication between Grafana and the renderer. If you’re using API keys for Grafana’s internal communication, ensure they are correctly configured and not expired. For grafana-image-renderer, the render_token setting in grafana.ini can be used for basic authentication between Grafana and the renderer if they are not on the same trusted network.
    • Why it works: The renderer might have its own internal security settings, or Grafana might be configured to use a token that the renderer doesn’t recognize, preventing the request from being processed.
  6. Report Configuration (Timezones, Permissions): While not a system-level renderer issue, incorrect report settings can lead to empty or failed reports.

    • Diagnosis: Check the specific report configuration within Grafana. Ensure the time range is valid and the dashboard itself is accessible to the user account Grafana is using for rendering (especially if using role-based access control).
    • Fix: Adjust the report’s time range to something reasonable. Verify the dashboard’s permissions. Ensure the report owner has access to view the dashboard.
    • Why it works: If the dashboard data doesn’t exist for the specified time range, or if Grafana lacks the permissions to query the data sources for that dashboard, the rendered PDF will be blank or the report generation will fail with a permission error.

Once you’ve addressed these, your next challenge might be ensuring the email sending itself is configured correctly, or dealing with very large dashboards that hit resource limits on the renderer.

Want structured learning?

Take the full Grafana course →