-
What Grafana version and what operating system are you using?
- Grafana v11.1.4 (13173c9874)
- latest, of 22/10/2025 (7efef0feee0192f6a90a3bd13f7062c5c08a7d18ee6c79cd863c176550ca3d7d)
-
What are you trying to achieve?
- Get an image of a dashboard from Grafana
-
How are you trying to achieve it?
- Deploying Image renderer
-
What happened?
- We are getting an image of the login page in Grafana
-
What did you expect to happen?
- Get the dashboard image
-
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.
- getting different errors in the image-renderer pod:
-
{"level":"error","message":"Browser console error","msg":"Failed to load resource: the server responded with a status of 404 ()","url":"https://<OUR_SUB_DOMAIN>.cloudflareaccess.com/favicon.ico"} {"file":"/tmp/f4768b44.png","level":"debug","message":"Deleting temporary file"} {"level":"debug","message":"::ffff:127.0.0.1 - - [22/Oct/2025:09:18:39 +0000] \"GET /render?url=http%3a%2f%2fadmin%3...NK%40grafana.<OUR_DOMAIN>%2fd%2fcollector-pipeline%2fcollector-pipeline-monitoring%3forgId%3d1%26kiosk&encoding=png HTTP/1.1\" 200 22308 \"-\" \"curl/8.11.1\"\n"} --- {"level":"error","message":"::ffff:127.0.0.1 - - [22/Oct/2025:09:22:17 +0000] \"GET /render?encoding=png&url=http://image-render:Vi6...Xv@grafana.<OUR_DOMAIN>/d/collector-pipeline/collector-pipeline-monitoring?orgId=1&kiosk=&CF-Access-Client-Id=6.....1c.access&CF-Access-Client-Secret=a...e&X-Auth-Token=b...1 HTTP/1.1\" 401 74 \"-\" \"PostmanRuntime/7.46.1\"\n"} ---
-
Did you follow any online instructions? If so, what is the URL?
Those are the configurations we used:
We have Grafana installed as part of the kube-prometheus-stack on our GKE cluster using it’s official helm chart. We use ArgoCD and configure
- chart: kube-prometheus-stack repoURL: https://prometheus-community.github.io/helm-charts/ targetRevision: 62.3.0
Those are the relevant parts from the values file
grafana:
enabled: true
namespaceOverride: “”
envFromSecrets:
- name: oauth-client-id
- name: oauth-secret
- name: grafana-password
- name: grafana-image-rendering-token
plugins:
- grafana-clock-panel
- grafana-image-renderer
securityContext:
runAsUser: 472
runAsGroup: 0
fsGroup: 472
fsGroupChangePolicy: “OnRootMismatch”
grafana.ini:
server:
root_url: https://grafana.<OUR_DOMAIN>
auth.google:
enabled: true
name: Google
…
log:
mode: console
level: debug
rendering:
# server_url: http://image-renderer.default.svc.cluster.local/render
# callback_url: http://prometheus-grafana.default.svc.cluster.local/
auth_token: $__env{grafana-image-rendering-token}
unified_alerting:
screenshots:
capture: true
upload_external_image_storage: false
max_concurrent_screenshots: 5
grafana_net:
…
serviceAccount:
create: true
autoMount: true
annotations:
iam.gke.io/gcp-service-account: prometheus-grafana@be-testing-429605.iam.gserviceaccount.com
env:
GF_RENDERING_SERVER_URL: https://grafana.<OUR_DOMAIN>/render
GF_RENDERING_CALLBACK_URL: https://grafana.<OUR_DOMAIN>/grafana
GF_UNIFIED_ALERTING_SCREENSHOTS_CAPTURE: true
GF_UNIFIED_ALERTING_SCREENSHOTS_UPLOAD_EXTERNAL_IMAGE_STORAGE: false
GF_LOG_LEVEL: debug
GF_LOG_FILTERS: “rendering:debug”
We deploy grafana-image-renderer using those 2 yamls:
grafana-image-renderer-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: image-renderer
namespace: prometheus
spec:
selector:
matchLabels:
app.kubernetes.io/name:`` image-renderer
replicas: 1
template:
metadata:
labels:
app.kubernetes.io/name:`` image-renderer
spec:
containers:
- name: image-renderer
image: ``docker.io/grafana/grafana-image-renderer:latest
ports:
- containerPort: 8081
name: http
env:
- name: ENABLE_METRICS
value: “true”
- name: LOG_LEVEL
value: “debug”
- name: AUTH_TOKEN
valueFrom:
secretKeyRef:
name: grafana-image-rendering-token
key: GF_RENDERING_AUTH_TOKEN
grafana-image-renderer-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: image-renderer
namespace: prometheus
spec:
selector:
app.kubernetes.io/name:`` image-renderer
ports:
- name: http
protocol: TCP
port: 80
targetPort: http
We try to send requests in the following manner:
curl --location 'https://grafana.<OUR_DOMAIN>/render?url=https://grafana.<OUR_DOMAIN>/d-solo/alertmanager-overview/alertmanager-overview?kiosk=1&width=1200&height=600' \ --header 'Authorization: Bearer glsa_2rZP....52' \ --output image-renderer-output.png
The Authorization: Bearer values is from a token of a service account we created in Grafana.
But we always getting only the Grafana login page.
What are we missing?
Every suggestion would be much appreciated - we done a lot of different tries and invested a lot of time into this.
Anything else we need to know?:
We also have a Zero-Trust configuration (Cloud-Flare) which we want to bypass when sending the requests.
We have CF-Access-Client-Id & CF-Access-Client-Secret. We disable Cloud-Flare when doing testing, but also want to know how to send the request when it’s active. (Preferably the communication between Grafana ↔ Image Renderer should be internal so it shouldn’t even encounter Cloud-Flare.