<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Set up image rendering on Grafana Labs</title><link>https://grafana.com/docs/grafana/v12.4/setup-grafana/image-rendering/</link><description>Recent content in Set up image rendering on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/grafana/v12.4/setup-grafana/image-rendering/index.xml" rel="self" type="application/rss+xml"/><item><title>Troubleshoot image rendering</title><link>https://grafana.com/docs/grafana/v12.4/setup-grafana/image-rendering/troubleshooting/</link><pubDate>Fri, 03 Apr 2026 12:35:46 -0500</pubDate><guid>https://grafana.com/docs/grafana/v12.4/setup-grafana/image-rendering/troubleshooting/</guid><content><![CDATA[&lt;h1 id=&#34;troubleshooting&#34;&gt;Troubleshooting&lt;/h1&gt;
&lt;p&gt;This section answers common questions about troubleshooting the image renderer.
The guidance is helpful for self-managed Grafana users.
It isn&amp;rsquo;t particularly useful for Grafana Cloud users, as the image renderer is managed for you.&lt;/p&gt;
&lt;h2 id=&#34;available-configuration-options&#34;&gt;Available configuration options&lt;/h2&gt;
&lt;p&gt;To see all available options, run:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;docker run --rm grafana/grafana-image-renderer:latest server --help&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Much of the service&amp;rsquo;s functionality has configurable options.
When troubleshooting the image renderer, these options are often the first ones to change.&lt;/p&gt;
&lt;p&gt;The rest of this guide clarifies what these options are and do, so you can make the right experiments and changes.&lt;/p&gt;
&lt;h2 id=&#34;configuration-file-formats-and-paths&#34;&gt;Configuration file formats and paths&lt;/h2&gt;
&lt;p&gt;The service reads configuration files from its current working directory.
With Docker images, this is &lt;code&gt;/home/nonroot/&lt;/code&gt; by default.&lt;/p&gt;
&lt;p&gt;The file names must be one of &lt;code&gt;config.json&lt;/code&gt;, &lt;code&gt;config.yaml&lt;/code&gt;, or &lt;code&gt;config.yml&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;monitor-the-image-renderer&#34;&gt;Monitor the image renderer&lt;/h2&gt;
&lt;p&gt;You can monitor the service using Prometheus or &lt;a href=&#34;/oss/mimir&#34;&gt;Grafana Mimir&lt;/a&gt; for metrics and any OpenTelemetry-compatible tracing backend for traces, such as &lt;a href=&#34;/oss/tempo&#34;&gt;Grafana Tempo&lt;/a&gt;.
We recommend setting up both:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Point the metrics scraper to &lt;code&gt;/metrics&lt;/code&gt; on the HTTP port (default &lt;code&gt;:8081&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Point the service (&lt;code&gt;--tracing.endpoint&lt;/code&gt;) to the tracing backend.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a pre-built monitoring dashboard, refer to this &lt;a href=&#34;/grafana/dashboards/12203-grafana-image-renderer/&#34;&gt;example dashboard&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;change-the-http-server-bind-address&#34;&gt;Change the HTTP server bind address&lt;/h2&gt;
&lt;p&gt;Use the &lt;code&gt;--server.addr&lt;/code&gt; option to change the HTTP server bind address.&lt;/p&gt;
&lt;p&gt;If no specific address is given, it listens on all interfaces.
The syntax to only change the port is &lt;code&gt;:8081&lt;/code&gt; or any other port number.&lt;/p&gt;
&lt;h2 id=&#34;use-multiple-authentication-tokens&#34;&gt;Use multiple authentication tokens&lt;/h2&gt;
&lt;p&gt;Specify the option multiple times, for example: &lt;code&gt;--server.auth-token &amp;lt;token1&amp;gt; --server.auth-token &amp;lt;token2&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you use JSON or YAML, you can use a list:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;server:
  auth-token:
    - &amp;lt;token1&amp;gt;
    - &amp;lt;token2&amp;gt;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For environment variables, use a comma-separated list.&lt;/p&gt;
&lt;h2 id=&#34;change-the-logging-level&#34;&gt;Change the logging level&lt;/h2&gt;
&lt;p&gt;Use the &lt;code&gt;--log.level&lt;/code&gt; option to change the log level.&lt;/p&gt;
&lt;p&gt;Valid values are &lt;code&gt;debug&lt;/code&gt;, &lt;code&gt;info&lt;/code&gt;, &lt;code&gt;warn&lt;/code&gt;, and &lt;code&gt;error&lt;/code&gt;.
&lt;code&gt;debug&lt;/code&gt; is &lt;em&gt;very&lt;/em&gt; verbose.
Production deployments should usually use &lt;code&gt;info&lt;/code&gt; or &lt;code&gt;warn&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;set-up-tls-on-the-http-server&#34;&gt;Set up TLS on the HTTP server&lt;/h2&gt;
&lt;p&gt;You can serve the HTTP server over TLS (HTTPS) using the following options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--server.certificate-file&lt;/code&gt;&lt;/strong&gt;: Path to the TLS certificate file in PEM format.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--server.key-file&lt;/code&gt;&lt;/strong&gt;: Path to the TLS private key file in PEM format.
This must be the matching key for the given certificate file.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--server.min-tls-version&lt;/code&gt;&lt;/strong&gt;: Minimum TLS version to accept.
Valid values are &lt;code&gt;1.0&lt;/code&gt;, &lt;code&gt;1.1&lt;/code&gt;, &lt;code&gt;1.2&lt;/code&gt; (default), and &lt;code&gt;1.3&lt;/code&gt;.
The default value is sufficient for most security-conscious users.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mutual TLS (mTLS) isn&amp;rsquo;t supported at this time.&lt;/p&gt;
&lt;h2 id=&#34;set-up-mtls-with-the-tracing-backend&#34;&gt;Set up mTLS with the tracing backend&lt;/h2&gt;
&lt;p&gt;You can set up mTLS for the connection to the tracing backend using the following options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--tracing.trusted-certificate&lt;/code&gt;&lt;/strong&gt;: Path to the trusted CA certificate file in PEM format.
This is used to verify the tracing backend&amp;rsquo;s certificate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--tracing.client-certificate&lt;/code&gt;&lt;/strong&gt;: Path to the client certificate file in PEM format.
This is used to authenticate to the tracing backend.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--tracing.client-key&lt;/code&gt;&lt;/strong&gt;: Path to the client private key file in PEM format.
This must be the matching key for the given client certificate file.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;use-a-custom-browser-binary&#34;&gt;Use a custom browser binary&lt;/h2&gt;
&lt;p&gt;Use the &lt;code&gt;--browser.path&lt;/code&gt; option to set the browser binary.&lt;/p&gt;
&lt;p&gt;The browser must support the Chrome DevTools Protocol, which limits the choices somewhat.
This works fine with Chromium, Google Chrome, Microsoft Edge, Brave, and other similar browsers based on Chromium.&lt;/p&gt;
&lt;p&gt;Only Chromium is officially supported.
If a bug can&amp;rsquo;t be replicated with Chromium, the bug may not be prioritized or closed without a fix.&lt;/p&gt;
&lt;h2 id=&#34;use-gpu-acceleration&#34;&gt;Use GPU acceleration&lt;/h2&gt;
&lt;p&gt;Enable GPU acceleration in the browser using the &lt;code&gt;--browser.gpu&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;On some environments, such as Docker, Kubernetes, or other container and VM runtimes, you may need further configuration to pass the GPU through to the service.&lt;/p&gt;
&lt;h2 id=&#34;enable-custom-flags-in-the-browser&#34;&gt;Enable custom flags in the browser&lt;/h2&gt;
&lt;p&gt;Pass flags to the browser using the &lt;code&gt;--browser.flag&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;The format is &lt;code&gt;--${flag}=${value}&lt;/code&gt; or &lt;code&gt;--${flag}&lt;/code&gt;, with the &lt;code&gt;--&lt;/code&gt; prefix being required. The parser splits each browser flag based on them.&lt;/p&gt;
&lt;p&gt;For example, &lt;code&gt;--browser.flag=--headless=false --host-resolver-rules=MAP * 127.0.0.1, EXCLUDE grafana --no-sandbox&lt;/code&gt; enables headful mode, forces the browser to resolve all network requests to &lt;code&gt;127.0.0.1&lt;/code&gt; with exception of the &lt;code&gt;grafana&lt;/code&gt; host, and disables sandbox mode.&lt;/p&gt;
&lt;h2 id=&#34;enable-the-browser-sandbox&#34;&gt;Enable the browser sandbox&lt;/h2&gt;
&lt;p&gt;Enable the sandbox using the &lt;code&gt;--browser.sandbox&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;On some Linux distributions, in Docker, Kubernetes, OpenShift, and other container and VM setups, this may not work out of the box.
You may need to enable various virtualization features, &lt;code&gt;seccomp&lt;/code&gt; profiles, AppArmor profiles, Linux capabilities, and more.&lt;/p&gt;
&lt;h2 id=&#34;use-linux-namespaces-for-request-isolation&#34;&gt;Use Linux namespaces for request isolation&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-caution&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Caution&lt;/p&gt;&lt;p&gt;Although there is an option to enable Linux namespaces, the functionality is unsupported.
Proceed at your own risk, and ensure the option is disabled before reporting bugs.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;To use new Linux namespaces for each rendering request, isolating the entire browser from the service and other requests, use the &lt;code&gt;--browser.namespaced&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;This functionality requires Linux and various capabilities and AppArmor profiles to be set up.&lt;/p&gt;
&lt;h2 id=&#34;change-the-default-browser-time-zone&#34;&gt;Change the default browser time zone&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Every request can override this in the request query parameters.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;To change the default time zone, set the &lt;code&gt;--browser.timezone&lt;/code&gt; option to an IANA time zone name.
For example, &lt;code&gt;America/Los_Angeles&lt;/code&gt; or &lt;code&gt;Europe/Berlin&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Many containers automatically set a &lt;code&gt;TZ&lt;/code&gt; environment variable.
This is used by default.&lt;/p&gt;
&lt;h2 id=&#34;add-a-header-to-every-request-from-the-browser&#34;&gt;Add a header to every request from the browser&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;Depending on the target website&amp;rsquo;s CORS settings, this may break all requests.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;You can set a new header with &lt;code&gt;--browser.header &amp;lt;name&amp;gt;=&amp;lt;value&amp;gt;&lt;/code&gt;.
This header is added to every request made by the browser.&lt;/p&gt;
&lt;h2 id=&#34;pass-through-a-trace-header-to-every-request-from-the-browser&#34;&gt;Pass through a trace header to every request from the browser&lt;/h2&gt;
&lt;p&gt;This is enabled by default if tracing is set up.
Outgoing requests receive a &lt;code&gt;Traceparent&lt;/code&gt; header.&lt;/p&gt;
&lt;p&gt;If the incoming request to the service has a &lt;code&gt;Traceparent&lt;/code&gt; header, that value is used.
Otherwise, a new trace is started for every request.&lt;/p&gt;
&lt;h2 id=&#34;understand-incomplete-outputs-and-request-timeouts&#34;&gt;Understand incomplete outputs and request timeouts&lt;/h2&gt;
&lt;p&gt;The browser waits for the web page to become ready.
This is done by waiting for all of the following to complete or time out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scrolls all the web-ports (that is, to load the entire page).
&lt;ul&gt;
&lt;li&gt;After every scroll, the browser waits the duration declared by the &lt;code&gt;--browser.scroll-wait&lt;/code&gt; option, 50 milliseconds by default.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The browser waits the duration declared by the &lt;code&gt;--browser.readiness.prior-wait&lt;/code&gt; option, 1 second by default.&lt;/li&gt;
&lt;li&gt;The entire following sequence times out after the duration declared by the &lt;code&gt;--browser.readiness.timeout&lt;/code&gt; option, 30 seconds by default:
&lt;ul&gt;
&lt;li&gt;The sequence is repeated per duration declared by the &lt;code&gt;--browser.readiness.interval&lt;/code&gt; option, 100 milliseconds by default.&lt;/li&gt;
&lt;li&gt;The browser waits for all Grafana queries to complete, unless the &lt;code&gt;--browser.readiness.disable-query-wait&lt;/code&gt; option is enabled.
This functionality requires Scenes to be enabled.
If Scenes aren&amp;rsquo;t enabled, the check is skipped silently.
&lt;ul&gt;
&lt;li&gt;If the queries don&amp;rsquo;t complete within the duration declared by the &lt;code&gt;--browser.readiness.give-up-on-all-queries&lt;/code&gt; option, the check is silently skipped.
By default, this timeout is disabled.&lt;/li&gt;
&lt;li&gt;If there is no first query detected within the duration declared by the &lt;code&gt;--browser.readiness.give-up-on-first-query&lt;/code&gt; option, the check is silently skipped.
By default, this timeout is 3 seconds.&lt;/li&gt;
&lt;li&gt;If the &lt;code&gt;--browser.readiness.wait-for-n-query-cycles&lt;/code&gt; is set to a value greater than &lt;code&gt;1&lt;/code&gt;, the service waits for &lt;code&gt;N&lt;/code&gt; full query cycles to succeed before proceeding.
Each query cycle is separated by the duration as declared by the &lt;code&gt;--browser.readiness.interval&lt;/code&gt; option.
If any query timeout passes during these cycles, the check is silently skipped.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The browser waits for all network requests to complete, unless the &lt;code&gt;--browser.readiness.disable-network-wait&lt;/code&gt; option is enabled.
&lt;ul&gt;
&lt;li&gt;If the network requests don&amp;rsquo;t complete within the duration declared by the &lt;code&gt;--browser.readiness.network-idle-timeout&lt;/code&gt; option, the check is silently skipped.
By default, this timeout is disabled.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The browser waits for the web page&amp;rsquo;s layout to stabilise, meaning no more data changes.
This can be disabled through the &lt;code&gt;--browser.readiness.disable-dom-hashcode-wait&lt;/code&gt; option.
&lt;ul&gt;
&lt;li&gt;If the web page doesn&amp;rsquo;t stabilise within the duration declared by the &lt;code&gt;--browser.readiness.dom-hashcode-timeout&lt;/code&gt; option, the check is silently skipped.
By default, this timeout is disabled.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;the-service-eats-up-all-the-memory-in-the-container&#34;&gt;The service eats up all the memory in the container&lt;/h2&gt;
&lt;p&gt;Set the &lt;code&gt;GOMEMLIMIT&lt;/code&gt; environment variable to a lower value than the container&amp;rsquo;s memory limit, such as &lt;code&gt;1GiB&lt;/code&gt;.
The value shouldn&amp;rsquo;t be the same as the container&amp;rsquo;s memory limit, because Chromium needs free memory to serve requests.&lt;/p&gt;
&lt;p&gt;We recommend adding 1 GiB to this environment variable for every 8 GiB of memory assigned to the container&amp;rsquo;s memory limit.&lt;/p&gt;
&lt;h2 id=&#34;unsupported-cpu-architectures&#34;&gt;Unsupported CPU architectures&lt;/h2&gt;
&lt;p&gt;For unsupported CPU architectures, you can open an issue on &lt;a href=&#34;https://github.com/grafana/grafana-image-renderer&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Alternatively, compile the service yourself, following the instructions in the &lt;a href=&#34;https://github.com/grafana/grafana-image-renderer&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;use-the-image-renderer-service-in-an-air-gapped-environment&#34;&gt;Use the image renderer service in an air-gapped environment&lt;/h2&gt;
&lt;p&gt;An air-gapped environment is one that doesn&amp;rsquo;t have access to the public internet, and may have requirements such as not supporting Docker.&lt;/p&gt;
&lt;p&gt;Grafana Enterprise customers can receive more help with this from customer support.&lt;/p&gt;
&lt;h3 id=&#34;with-docker&#34;&gt;With Docker&lt;/h3&gt;
&lt;p&gt;Before you begin, ensure you have the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A way to transfer data into the environment, such as a USB stick, SD card, external hard-drive, or similar.&lt;/li&gt;
&lt;li&gt;Docker on the air-gapped environment.&lt;/li&gt;
&lt;li&gt;Docker on an internet-connected environment.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To export a TAR file of the image, run:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;docker image save -o grafana-image-renderer.tar grafana/grafana-image-renderer:latest&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;If you&amp;rsquo;re using a different CPU architecture than the air-gapped environment, you may need to specify &lt;code&gt;--platform&lt;/code&gt; when saving the image.
For example, if you have an air-gapped x86_64 (amd64) machine, use &lt;code&gt;--platform linux/amd64&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Next, transfer the file to the machine.&lt;/p&gt;
&lt;p&gt;Finally, import the image on the air-gapped environment:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;docker image load grafana-image-renderer.tar&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;without-docker&#34;&gt;Without Docker&lt;/h3&gt;
&lt;p&gt;Before you begin, ensure you have the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A way to transfer data into the environment, such as a USB stick, SD card, external hard-drive, or similar.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We release binary files for Linux and Windows on our &lt;a href=&#34;https://github.com/grafana/grafana-image-renderer/releases&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;GitHub Releases&lt;/a&gt; page.
Download the appropriate binary for your system, and transfer it to the machine.&lt;/p&gt;
&lt;p&gt;You will also need to install a Chromium-based browser separately.&lt;/p&gt;
&lt;h2 id=&#34;use-docker-without-grafana-being-dockerised&#34;&gt;Use Docker without Grafana being dockerised&lt;/h2&gt;
&lt;p&gt;You can use &lt;a href=&#34;https://docs.docker.com/engine/network/tutorials/host/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;host networking&lt;/a&gt; instead, or the binary releases.&lt;/p&gt;
&lt;h2 id=&#34;use-the-image-renderer-service-on-windows-without-docker&#34;&gt;Use the image renderer service on Windows without Docker&lt;/h2&gt;
&lt;p&gt;You can download the Windows binaries from the &lt;a href=&#34;https://github.com/grafana/grafana-image-renderer/releases&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;GitHub Releases page&lt;/a&gt;.
For example, to use the image renderer service with the Brave browser on an ARM64 Windows host, run:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;powershell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-powershell&#34;&gt;.\grafana-image-renderer-windows-arm64.exe server --browser.path &amp;#34;C:\Program Files\BraveSoftware\Brave-Browser\Application\brave.exe&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The browser must be installed separately and be a Chromium-based browser.&lt;/p&gt;
&lt;h2 id=&#34;custom-ca-certificates-in-chromium&#34;&gt;Custom CA certificates in Chromium&lt;/h2&gt;
&lt;p&gt;Identifying that the CA certificate is the problem is done by checking for &lt;code&gt;net::ERR_CERT_AUTHORITY_INVALID&lt;/code&gt; errors in the service&amp;rsquo;s logs.
Finding these errors may require enabling debug logging via the &lt;code&gt;--log.level debug&lt;/code&gt; option.&lt;/p&gt;
&lt;h3 id=&#34;non-containerized-linux&#34;&gt;Non-containerized Linux&lt;/h3&gt;
&lt;p&gt;For non-containerized Linux, you need &lt;code&gt;nss&lt;/code&gt; tools (&lt;code&gt;libnss3-tools&lt;/code&gt; on Debian).
You will also need to know the &lt;code&gt;$HOME&lt;/code&gt; directory of the user running the service, which can be found via running either &lt;code&gt;eval echo ~&amp;lt;username&amp;gt;&lt;/code&gt; (for example: &lt;code&gt;eval echo ~grafana&lt;/code&gt;) or &lt;code&gt;getent passwd &amp;lt;username&amp;gt;&lt;/code&gt; (for example: &lt;code&gt;getent passwd grafana&lt;/code&gt;).
Run the following for that user:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;shell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-shell&#34;&gt;certutil -d sql:&amp;#34;$HOME&amp;#34;/.pki/nssdb -A -n internal-root-ca -t C -i /path/to/internal-root-ca-here.crt.pem&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You might also need other tooling.
The error message will likely indicate what is missing from your environment.&lt;/p&gt;
&lt;h3 id=&#34;non-containerized-windows&#34;&gt;Non-containerized Windows&lt;/h3&gt;
&lt;p&gt;For non-containerized, you need to do the same as on Linux, but to your global store:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;powershell&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-powershell&#34;&gt;certutil –addstore &amp;#34;Root&amp;#34; &amp;lt;path&amp;gt;/internal-root-ca-here.crt.pem&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;container&#34;&gt;Container&lt;/h3&gt;
&lt;p&gt;The easiest way is to integrate the CA certificate directly into your own Docker image, based on the official one:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;dockerfile&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-dockerfile&#34;&gt;# Consider using a pinned version.
FROM grafana/grafana-image-renderer:latest

# Elevate our permissions to access system resources.
USER root

RUN mkdir -p /usr/local/share/ca-certificates/
# Convert from .pem to .crt
RUN openssl x509 -inform PEM -in rootCA.pem -out /usr/local/share/ca-certificates/rootCA.crt

# Regenerate the CA certificates in the container.
RUN update-ca-certificates --fresh

# Reassume the nonroot user for the service execution.
USER nonroot
# Note: for Kubernetes, OpenShift, and other setups, this may need a numeric ID. See the upstream Dockerfile for which UID to use.

# Some CA certificates also need to explicitly be included in the user&amp;#39;s network security services database.
RUN mkdir -p /home/nonroot/.pki/nssdb
RUN certutil -d sql:/home/nonroot/.pki/nssdb -A -n internal-root-ca -t C -i /usr/local/share/ca-certificates/rootCA.crt&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;distorted-panels-in-the-pdf-export&#34;&gt;Distorted panels in the PDF export&lt;/h2&gt;
&lt;p&gt;This is most commonly caused by using the old PDF rendering engine in Grafana.
To identify whether this applies to you, check whether the &lt;code&gt;newPDFRendering&lt;/code&gt; feature flag has been explicitly set to &lt;code&gt;false&lt;/code&gt; in Grafana&amp;rsquo;s configuration.&lt;/p&gt;
&lt;p&gt;To solve this problem, remove the feature toggle override.&lt;/p&gt;
&lt;h2 id=&#34;debug-the-configuration&#34;&gt;Debug the configuration&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;The command recommended here prints secrets and sensitive information in
plain text. Be careful when sharing the output or storing it in logs.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;When the service doesn&amp;rsquo;t appear to be working as expected, it can be because the
configuration is invalid. If the flags are invalid, the service won&amp;rsquo;t start, but
the configuration files may contain unknown keys and thus silently ignore them.&lt;/p&gt;
&lt;p&gt;To debug that the configuration is valid and what you expect, you can get a full
dump of the Go structures representing the configuration by running the
&lt;code&gt;print-config&lt;/code&gt; command. For example:&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;docker run --rm -v ./config.json:/home/nonroot/config.json grafana/grafana-image-renderer:latest print-config&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The command takes the exact same flags and configuration files as the &lt;code&gt;server&lt;/code&gt;
command does.&lt;/p&gt;
&lt;h2 id=&#34;limiting-accessible-domains&#34;&gt;Limiting accessible domains&lt;/h2&gt;
&lt;p&gt;It is possible to limit which domains the browser can access by using &lt;a href=&#34;https://support.google.com/chrome/a/answer/9027408?hl=en&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;Chrome policies&lt;/a&gt;. To limit this, mount a Chrome policy JSON file into &lt;code&gt;/etc/chromium/policies/managed/&lt;/code&gt;, with contents such as:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JSON&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-json&#34;&gt;{
  &amp;#34;URLBlocklist&amp;#34;: [&amp;#34;*&amp;#34;],
  &amp;#34;URLAllowlist&amp;#34;: [&amp;#34;https://*&amp;#34;, &amp;#34;chrome://*&amp;#34;]
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="troubleshooting">Troubleshooting&lt;/h1>
&lt;p>This section answers common questions about troubleshooting the image renderer.
The guidance is helpful for self-managed Grafana users.
It isn&amp;rsquo;t particularly useful for Grafana Cloud users, as the image renderer is managed for you.&lt;/p></description></item><item><title>Image rendering flags</title><link>https://grafana.com/docs/grafana/v12.4/setup-grafana/image-rendering/flags/</link><pubDate>Fri, 03 Apr 2026 12:35:46 -0500</pubDate><guid>https://grafana.com/docs/grafana/v12.4/setup-grafana/image-rendering/flags/</guid><content><![CDATA[&lt;h1 id=&#34;image-rendering-flags&#34;&gt;Image rendering flags&lt;/h1&gt;
&lt;p&gt;This section aims to list the entire set of flags that can be used to configure the image rendering service.&lt;/p&gt;
&lt;h2 id=&#34;configuration-format&#34;&gt;Configuration format&lt;/h2&gt;
&lt;p&gt;To configure the service, any of the following methods can be used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Set CLI flags. These are passed in on the command line, and take complete precedence over all other methods.
For example, &lt;code&gt;--server.addr=&amp;quot;:8081&amp;quot;&lt;/code&gt; sets the HTTP address to listen on all interfaces on port &lt;code&gt;8081&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Set environment variables. These are set in the environment.
If environment variables are supported for a flag, they are listed in the help command.&lt;/li&gt;
&lt;li&gt;Write a JSON or YAML configuration file. These must be named &lt;code&gt;config.json&lt;/code&gt;, &lt;code&gt;config.yaml&lt;/code&gt;, or &lt;code&gt;config.yml&lt;/code&gt;.
There should only be one file; precedence is undefined if multiple files are present.
Dot-separated keys are nested keys. For example, the flag &lt;code&gt;a.b&lt;/code&gt; becomes &lt;code&gt;{&amp;quot;a&amp;quot;: {&amp;quot;b&amp;quot;: &amp;quot;VALUE&amp;quot;}}&lt;/code&gt; in the file.
The configuration keys are always mentioned in the help command alongside the flag.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, a complete configuration file might look like this in YAML:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;server:
  addr: &amp;#34;:8081&amp;#34; # server.addr
  auth-token: # server.auth-token
    - &amp;#34;a&amp;#34;
    - &amp;#34;b&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;list-of-flags&#34;&gt;List of flags&lt;/h2&gt;
&lt;p&gt;The following is a complete list of all flags that are currently supported in the latest release.
This is a verbatim copy of the output of the &lt;code&gt;grafana-image-renderer server --help&lt;/code&gt; command.&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;--api.default-encoding=&amp;lt;string&amp;gt; [default: &amp;#34;pdf&amp;#34;] [${API_DEFAULT_ENCODING}]
    The default encoding for render requests when not specified. (values: pdf, png) [config: api.default-encoding]
--api.silence-request-log-path=&amp;lt;string&amp;gt; [${API_SILENCE_REQUEST_LOG_PATH}]
    Allows silencing the HTTP request logs for a certain path. It requires a direct match. Multiple values can be passed separated by comma or multiple flags. Examples: &amp;#39;/healthz&amp;#39;, &amp;#39;/render/version&amp;#39;. [config: api.silence-request-log-path]
--browser.flag=&amp;lt;string&amp;gt; / --browser.flags=&amp;lt;string&amp;gt; [${BROWSER_FLAGS}, ${BROWSER_FLAG}]
    Flags to pass to the browser. These are syntaxed `--${flag}` or `--${flag}=${value}`. Note the required `--` prefix for each flag. [config: browser.flag]
--browser.force-polling-mode [default: false] [${BROWSER_FORCE_POLLING_MODE}]
    Forces the renderer to poll for scenes&amp;#39; query running count variable to detect when rendering is done, rather than use an event-based approach even when that is available. [config: browser.force-polling-mode]
--browser.gpu [default: false] [${BROWSER_GPU}]
    Enable GPU support in the browser. [config: browser.gpu]
--browser.header=&amp;lt;string&amp;gt; / --browser.headers=&amp;lt;string&amp;gt; [${BROWSER_HEADER}]
    Headers to add to every request the browser makes. Syntax is `${key}=${value}`. May be repeated. [config: browser.header]
--browser.max-height=&amp;lt;int&amp;gt; [default: 3000] [${BROWSER_MAX_HEIGHT}]
    The maximum height of the browser viewport. Requests cannot request a larger height than this, except for when capturing full-page screenshots. Negative means ignored. [config: browser.max-height]
--browser.max-width=&amp;lt;int&amp;gt; [default: 3000] [${BROWSER_MAX_WIDTH}]
    The maximum width of the browser viewport. Requests cannot request a larger width than this. Negative means ignored. [config: browser.max-width]
--browser.min-height=&amp;lt;int&amp;gt; [default: 500] [${BROWSER_MIN_HEIGHT}]
    The minimum height of the browser viewport. This is the default height in requests. [config: browser.min-height]
--browser.min-width=&amp;lt;int&amp;gt; [default: 1000] [${BROWSER_MIN_WIDTH}]
    The minimum width of the browser viewport. This is the default width in requests. [config: browser.min-width]
--browser.namespaced [default: false] [${BROWSER_NAMESPACED}]
    Enable namespacing the browser. This requires Linux and the CAP_SYS_ADMIN and CAP_SYS_CHROOT capabilities, or a privileged user. [config: browser.namespaced]
--browser.override=&amp;lt;string&amp;gt; / --browser.overrides=&amp;lt;string&amp;gt; [${BROWSER_OVERRIDE}]
    URL pattern override in format: &amp;#39;pattern=--flag=value --flag2=value2&amp;#39;. Pattern is a regex. May be repeated. Example: --browser.override=&amp;#39;^https://slow\.example\.com/.*=--browser.readiness.timeout=60s&amp;#39; [config: browser.override]
--browser.page-scale-factor=&amp;lt;float&amp;gt; [default: 1] [${BROWSER_PAGE_SCALE_FACTOR}]
    The page scale factor of the browser. [config: browser.page-scale-factor]
--browser.path=&amp;lt;string&amp;gt; [default: &amp;#34;chromium&amp;#34;] [${BROWSER_PATH}]
    The path to the browser&amp;#39;s binary. This is resolved against PATH. [config: browser.path]
--browser.portrait [default: false] [${BROWSER_PORTRAIT}]
    Use a portrait viewport instead of the default landscape. [config: browser.portrait]
--browser.readiness.disable-dom-hashcode-wait [default: false] [${BROWSER_READINESS_DISABLE_DOM_HASHCODE_WAIT}]
    Disable waiting for the DOM to stabilize (i.e. not change) before capturing. [config: browser.readiness.disable-dom-hashcode-wait]
--browser.readiness.disable-network-wait [default: false] [${BROWSER_READINESS_DISABLE_NETWORK_WAIT}]
    Disable waiting for network requests to finish before capturing. [config: browser.readiness.disable-network-wait]
--browser.readiness.disable-query-wait [default: false] [${BROWSER_READINESS_DISABLE_QUERY_WAIT}]
    Disable waiting for queries to finish before capturing. [config: browser.readiness.disable-query-wait]
--browser.readiness.dom-hashcode-timeout=&amp;lt;duration&amp;gt; [default: 0s] [${BROWSER_READINESS_DOM_HASHCODE_TIMEOUT}]
    How long to wait before giving up on the DOM stabilizing (i.e. not changing). If &amp;lt;= 0, the timeout is disabled. [config: browser.readiness.dom-hashcode-timeout]
--browser.readiness.give-up-on-all-queries=&amp;lt;duration&amp;gt; [default: 0s] [${BROWSER_READINESS_GIVE_UP_ON_ALL_QUERIES}]
    How long to wait before giving up on all running queries. If &amp;lt;= 0, the give-up is disabled. [config: browser.readiness.give-up-on-all-queries]
--browser.readiness.give-up-on-first-query=&amp;lt;duration&amp;gt; [default: 3s] [${BROWSER_READINESS_GIVE_UP_ON_FIRST_QUERY}]
    How long to wait before giving up on a first query being registered. If &amp;lt;= 0, the give-up is disabled. [config: browser.readiness.give-up-on-first-query]
--browser.readiness.iteration-interval=&amp;lt;duration&amp;gt; [default: 100ms] [${BROWSER_READINESS_ITERATION_INTERVAL}]
    How long to wait between each iteration of checking whether the page is ready. Must be positive. [config: browser.readiness.iteration-interval]
--browser.readiness.network-idle-timeout=&amp;lt;duration&amp;gt; [default: 0s] [${BROWSER_READINESS_NETWORK_IDLE_TIMEOUT}]
    How long to wait before giving up on the network being idle. If &amp;lt;= 0, the timeout is disabled. [config: browser.readiness.network-idle-timeout]
--browser.readiness.prior-wait=&amp;lt;duration&amp;gt; [default: 1s] [${BROWSER_READINESS_PRIOR_WAIT}]
    The time to wait before checking for how ready the page is. This lets you force the webpage to take a beat and just do its thing before the service starts looking for whether it&amp;#39;s time to render anything. If &amp;lt;= 0, this is disabled. [config: browser.readiness.prior-wait]
--browser.readiness.timeout=&amp;lt;duration&amp;gt; [default: 30s] [${BROWSER_READINESS_TIMEOUT}]
    The maximum time to wait for a web-page to become ready (i.e. no longer loading anything). If &amp;lt;= 0, the timeout is disabled. [config: browser.readiness.timeout]
--browser.readiness.wait-for-n-query-cycles=&amp;lt;int&amp;gt; [default: 1] [${BROWSER_READINESS_WAIT_FOR_N_QUERY_CYCLES}]
    The number of readiness checks that must pass consecutively before considering the page ready. [config: browser.readiness.wait-for-n-query-cycles]
--browser.sandbox [default: false] [${BROWSER_SANDBOX}]
    Enable the browser&amp;#39;s sandbox. Sets the `no-sandbox` flag to `false` for you. [config: browser.sandbox]
--browser.time-between-scrolls=&amp;lt;duration&amp;gt; [default: 50ms] [${BROWSER_TIME_BETWEEN_SCROLLS}]
    The time between scroll events when capturing a full-page screenshot. [config: browser.time-between-scrolls]
--browser.time-zone=&amp;lt;string&amp;gt; / --browser.timezone=&amp;lt;string&amp;gt; / --browser.tz=&amp;lt;string&amp;gt; [default: &amp;#34;Etc/UTC&amp;#34;] [${BROWSER_TIMEZONE}, ${TZ}]
    The timezone for the browser to use, e.g. &amp;#39;America/New_York&amp;#39;. [config: browser.timezone]
--browser.user-agent=&amp;lt;string&amp;gt; [${BROWSER_USER_AGENT}]
    Sets the default User-Agent header for browser requests. If not set, Chromium&amp;#39;s default will be used instead. [config: browser.user-agent]
--browser.ws-url-read-timeout=&amp;lt;duration&amp;gt; [default: 0s] [${BROWSER_WS_URL_READ_TIMEOUT}]
    The timeout for reading the WebSocket URL when connecting to the browser. If &amp;lt;= 0, uses chromedp default (20s). [config: browser.ws-url-read-timeout]
--help / -h
    show help
--log.level=&amp;lt;string&amp;gt; [default: &amp;#34;info&amp;#34;] [${LOG_LEVEL}]
    The minimum level to log at (enum: debug, info, warn, error) [config: log.level]
--rate-limit.disabled [default: false] [${RATE_LIMIT_DISABLED}]
    Disable rate limiting entirely. [config: rate-limit.disabled]
--rate-limit.headroom=&amp;lt;uint&amp;gt; [default: 33554432] [${RATE_LIMIT_HEADROOM}]
    The amount of memory (in bytes) to leave as headroom after allocating memory for browser processes. Set to 0 to disable headroom. [config: rate-limit.headroom]
--rate-limit.max-available=&amp;lt;uint&amp;gt; [default: 0] [${RATE_LIMIT_MAX_AVAILABLE}]
    The maximum amount of memory (in bytes) available to processes. If more memory exists, only this amount is used. 0 disables the maximum. [config: rate-limit.max-available]
--rate-limit.max-limit=&amp;lt;uint&amp;gt; [default: 0] [${RATE_LIMIT_MAX_LIMIT}]
    The maximum number of requests to permit. Ratelimiting will reject requests if the number of currently running requests is at or above this value. Set to 0 to disable maximum. The v4 service used 5 by default. [config: rate-limit.max-limit]
--rate-limit.min-limit=&amp;lt;uint&amp;gt; [default: 3] [${RATE_LIMIT_MIN_LIMIT}]
    The minimum number of requests to permit. Ratelimiting will not reject requests if the number of currently running requests is below this value. Set to 0 to disable minimum (not recommended). [config: rate-limit.min-limit]
--rate-limit.min-memory-per-browser=&amp;lt;uint&amp;gt; [default: 67108864] [${RATE_LIMIT_MIN_MEMORY_PER_BROWSER}]
    The minimum amount of memory (in bytes) each browser process is expected to use. Set to 0 to disable the minimum. [config: rate-limit.min-memory-per-browser]
--rate-limit.process-tracker.decay=&amp;lt;int&amp;gt; [default: 5] [${RATE_LIMIT_PROCESS_TRACKER_DECAY}]
    The decay factor N to use in slow-moving averages of process statistics, where `avg = ((N-1)*avg &amp;#43; new) / N`. Must be at least 1. [config: rate-limit.process-tracker.decay]
--rate-limit.process-tracker.interval=&amp;lt;duration&amp;gt; [default: 50ms] [${RATE_LIMIT_PROCESS_TRACKER_INTERVAL}]
    How often to sample process statistics on the browser processes. Must be &amp;gt;= 1ms. [config: rate-limit.process-tracker.interval]
--server.addr=&amp;lt;string&amp;gt; [default: &amp;#34;:8081&amp;#34;] [${SERVER_ADDR}]
    The address to listen on for HTTP requests. [config: server.addr]
--server.auth-token=&amp;lt;string&amp;gt; / --server.auth-tokens=&amp;lt;string&amp;gt; / --server.token=&amp;lt;string&amp;gt; / --server.tokens=&amp;lt;string&amp;gt; [default: &amp;#34;-&amp;#34;] [${AUTH_TOKEN}]
    The X-Auth-Token header value that must be sent to the service to permit requests. May be repeated. [config: server.auth-token]
--server.cert-file=&amp;lt;string&amp;gt; / --server.cert=&amp;lt;string&amp;gt; / --server.certificate-file=&amp;lt;string&amp;gt; / --server.certificate=&amp;lt;string&amp;gt; [${SERVER_CERTIFICATE_FILE}]
    A path to a TLS certificate file to use for HTTPS. If not set, HTTP is used. [config: server.certificate-file]
--server.key-file=&amp;lt;string&amp;gt; / --server.key=&amp;lt;string&amp;gt; [${SERVER_KEY_FILE}]
    A path to a TLS key file to use for HTTPS. [config: server.key-file]
--server.min-tls-version=&amp;lt;string&amp;gt; [default: &amp;#34;1.2&amp;#34;] [${SERVER_MIN_TLS_VERSION}]
    The minimum TLS version to accept for HTTPS connections. (enum: 1.0, 1.1, 1.2, 1.3) [config: server.min-tls-version]
--tracing.client-certificate=&amp;lt;string&amp;gt; [${TRACING_CLIENT_CERTIFICATE}]
    A path to a PEM-encoded client certificate to use for mTLS when connecting to the tracing endpoint over gRPC or HTTPS. [config: tracing.client_certificate]
--tracing.client-key=&amp;lt;string&amp;gt; [${TRACING_CLIENT_KEY}]
    A path to a PEM-encoded client key to use for mTLS when connecting to the tracing endpoint over gRPC or HTTPS. [config: tracing.client_key]
--tracing.compressor=&amp;lt;string&amp;gt; [default: &amp;#34;none&amp;#34;] [${TRACING_COMPRESSOR}]
    The compression algorithm to use when sending traces. (enum: none, gzip) [config: tracing.compressor]
--tracing.endpoint=&amp;lt;string&amp;gt; [${TRACING_ENDPOINT}]
    The tracing endpoint to send spans to. Use grpc://, http://, or https:// to specify the protocol (grpc:// is implied). [config: tracing.endpoint]
--tracing.header=&amp;lt;string&amp;gt; / --tracing.headers=&amp;lt;string&amp;gt; [${TRACING_HEADER}]
    A header to add to requests to the tracing endpoint. Syntax is `${key}=${value}`. May be repeated. This is useful for things like authentication. [config: tracing.header]
--tracing.insecure [default: false] [${TRACING_INSECURE}]
    Whether to skip TLS verification when connecting. If set, the scheme in the endpoint is overridden to be insecure. [config: tracing.insecure]
--tracing.service-name=&amp;lt;string&amp;gt; [default: &amp;#34;grafana-image-renderer&amp;#34;] [${TRACING_SERVICE_NAME}]
    The service name to use in traces. [config: tracing.service_name]
--tracing.timeout=&amp;lt;duration&amp;gt; [default: 10s] [${TRACING_TIMEOUT}]
    The timeout for requests to the tracing endpoint. [config: tracing.timeout]
--tracing.trusted-certificate=&amp;lt;string&amp;gt; [${TRACING_TRUSTED_CERTIFICATE}]
    A path to a PEM-encoded certificate to use as a trusted root when connecting to the tracing endpoint over gRPC or HTTPS. [config: tracing.trusted_certificate]&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;debug-the-configuration&#34;&gt;Debug the configuration&lt;/h2&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;The command recommended here prints secrets and sensitive information in
plain text. Be careful when sharing the output or storing it in logs.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;p&gt;When the service doesn&amp;rsquo;t appear to be working as expected, it can be because the
configuration is invalid. If the flags are invalid, the service won&amp;rsquo;t start, but
the configuration files may contain unknown keys and thus silently ignore them.&lt;/p&gt;
&lt;p&gt;To debug that the configuration is valid and what you expect, you can get a full
dump of the Go structures representing the configuration by running the
&lt;code&gt;print-config&lt;/code&gt; command. For example:&lt;/p&gt;

&lt;div class=&#34;code-snippet code-snippet__mini&#34;&gt;&lt;div class=&#34;lang-toolbar__mini&#34;&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet code-snippet__border&#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-none&#34;&gt;docker run --rm -v ./config.json:/home/nonroot/config.json grafana/grafana-image-renderer:latest print-config&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The command takes the exact same flags and configuration files as the &lt;code&gt;server&lt;/code&gt;
command does.&lt;/p&gt;
]]></content><description>&lt;h1 id="image-rendering-flags">Image rendering flags&lt;/h1>
&lt;p>This section aims to list the entire set of flags that can be used to configure the image rendering service.&lt;/p>
&lt;h2 id="configuration-format">Configuration format&lt;/h2>
&lt;p>To configure the service, any of the following methods can be used:&lt;/p></description></item></channel></rss>