Custom icon not available in Canvas panel - even a copy of an existing icon does not work

  • What Grafana version and what operating system are you using?

12.3 on Ubuntu 24.04 LTS

  • What are you trying to achieve?

Use my custom icon on the Canvas panel. Since a simple SVG file I created was not getting loaded correctly, I went to the basics and attempted using an exact copy of a built-in icon.

(yes, followed the disccusion on creation of a Grafana compatible SVG file with stroke is unset correctly, etc.)

  • How are you trying to achieve it?

Let’s start with the following to create a copy of an existing icon that ships with Grafana and try using it in the Canvas panel. e.g.

cd /usr/share/grafana/public/img/icons/marker/
sudo cp circle.svg circle1.svg

sudo systemctl restart grafana
  • What happened?

Attempting to add the copied icon (circle1.svg) to the Canvas panel shows a blank in the icon picker

No matter what directory I place the copied icon in, or try to serve it from an accessible URL, I have the same issue.

  • What did you expect to happen?

I expect the icon to be available.

  • Can you copy/paste the configuration(s) that you are having problems with?

  • Did you receive any errors in the Grafana UI or in related logs? If so, please tell us exactly what they were.

  • No errros in the UI. What if any logs can I get?

  • Did you follow any online instructions? If so, what is the URL?

Canvas | Grafana documentationCanvas | Grafana documentation

Tried AI - both chatGPT and Gemini suggested disable_sanitize_html=true in grafana.ini. But that too has not helped.

Any pointers are appreciated. Thx.

Guess: file ownership/permissions. Of course you first debug should be: check the logs.

Do you also see anything in browser console?

Permissions for circle1.svg are exactly the same as for circle.svg
[…/public/img/icons/marker]$
total 40K
drwxr-xr-x 2 root root 4.0K Dec 28 22:15 ./
drwxr-xr-x 8 root root 4.0K Dec 21 19:25 ../
-rw-r–r-- 1 root root 98 Dec 28 22:15 circle1.svg
-rw-r–r-- 1 root root 98 Dec 16 06:36 circle.svg
-rw-r–r-- 1 root root 159 Dec 16 06:36 cross.svg
-rw-r–r-- 1 root root 642 Dec 16 06:36 plane.svg
-rw-r–r-- 1 root root 119 Dec 16 06:36 square.svg
-rw-r–r-- 1 root root 506 Dec 16 06:36 star.svg
-rw-r–r-- 1 root root 228 Dec 16 06:36 triangle.svg
-rw-r–r-- 1 root root 261 Dec 16 06:36 x-mark.svg

:3000/api/dashboards/uid/adkv999/public-dashboards:1   Failed to load resource: the server responded with a status of 404 (Not Found)

:3000/api/dashboards/uid/adljqvq/public-dashboards:1   Failed to load resource: the server responded with a status of 404 (Not Found)

:3000/public/build/img/icons/marker/circle1.svg:1   Failed to load resource: the server responded with a status of 404 (Not Found)

Why am I seeing a 404 for circle1.svg? It’s in the exact same location as circle.svg and has the same permissions as circle.svg.
Why is grafana looking in /public/build/img/icons/marker instead of /public/img/icons/marker?

If I place circle1.svg in /public/build/img/icons/marker, in addition to /usr/share/grafana/public/img/icons/marker, the issue is solved.

Definately a bug in the way grafana looks for these files.

IMHO it is not a bug, because doc doesn’t mention that you can load custom icon from the file system. Only load from URL is documented:

Add custom images to elements

You can add custom background images to all elements except Button by referencing an image URL. The image must be hosted at a URL that allows requests from your Grafana instance.

I understand. However, even with disable_sanitize_html=true in grafana.ini, I get this trying to access a copy of a built-in icon from an internal URL. Is there another way to disable the CORS issue within grafana?

Access to fetch at 'http://example.internal:8080/Icons/signal1.svg' from origin 'http://example.internal:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

index.mjs:62   GET http://example.internal:8080/Icons/signal1.svg net::ERR_FAILED 404 (File not found)

The internal site is a simple lightweight http service using python -m for testing purposes. This HTTP service is running on the same Ubuntu host as grafana. The file definately exists at this URL, and I can successfully serve Canvas Background images from this URL. It’s icons that are the issue.

That’s a CORS issue, not icon issue. You neeed to enable CORS (allow Grafana origin) on the server side (server which serves that icon):

inspect the icon and check the path and that path place your icon

Again, why is it that CORS is supposedly not enforced for background images, but is enforced for icons?

That path, as I mentioned earlier is accessible. Its a CORS issue that grafana enforces only on icons, not on background images.