Release notesRelease notes for Grafana 9.0.0

Release notes for Grafana 9.0.0

Features and enhancements

Bug fixes

  • Alerting: Fix database unavailable removes rules from scheduler. #49874, @grobinson-grafana
  • AzureMonitor: Fix auto-selection of time-grain for metrics. #49278, @aangelisc
  • DataSources: Fixes issue with expressions not being queried. #50446, @JoaoSilvaGrafana
  • GraphNG: Fix thresholds by color not following data update. #48571, @zoltanbedi
  • Jaeger: Update operations dropdown. #49329, @joey-grafana
  • Login: Fix mismatching label on auth_module in user list. #49177, @Jguer
  • Playlists: Save button now correctly creates a new playlist. #50381, @ashharrison90
  • RBAC: Fix migrations running in the wrong order causing inheritance problem in enterprise. #50452, @gamab
  • RBAC: Fix migrations running into the wrong order. (Enterprise)
  • ServiceAccounts: Add identifiable token prefix to service account tokens. #49011, @Jguer
  • Traces: Fix missing CopyButton on KeyValueTables and overlapping of panels. #49271, @svennergr

Breaking changes

The @grafana/ui package helper function selectOptionInTest used in frontend tests has been removed as it caused testing libraries to be bundled in the production code of Grafana. If you were using this helper function in your tests please update your code accordingly:

// before
import { selectOptionInTest } from '@grafana/ui';
// ...test usage
await selectOptionInTest(selectEl, 'Option 2');

// after
import { select } from 'react-select-event';
// ...test usage
await select(selectEl, 'Option 2', { container: document.body });

Issue #50442

Removed deprecated checkHealth prop from the @grafana/e2e addDataSource config. Previously this value defaulted to false, and has not been used in end-to-end tests since Grafana 8.0.3. Issue #50296

Removes the deprecated LegacyBaseMap, LegacyValueMapping, LegacyValueMap, and LegacyRangeMap types, and getMappedValue function from grafana-data. Migration is as follows:

Old New
LegacyBaseMap MappingType
LegacyValueMapping ValueMapping
LegacyValueMap ValueMap
LegacyRangeMap RangeMap
getMappedValue getValueMappingResult

This change fixes a bug in Grafana where intermittent failure of database, network between Grafana and the database, or error in querying the database would cause all alert rules to be unscheduled in Grafana. Following this change scheduled alert rules are not updated unless the query is successful.

The get_alert_rules_duration_seconds metric has been renamed to schedule_query_alert_rules_duration_seconds. Issue #49874

  • Any secret (data sources credential, alert manager credential, etc, etc) created or modified with Grafana v9.0 won’t be decryptable from any previous version (by default) because the way encrypted secrets are stored into the database has changed. Although secrets created or modified with previous versions will still be decryptable by Grafana v9.0.

  • If required, although generally discouraged, the disableEnvelopeEncryption feature toggle can be enabled to keep envelope encryption disabled once updating to Grafana v9.0.

  • In case of need to rollback to an earlier version of Grafana (i.e. Grafana v8.x) for any reason, after being created or modified any secret with Grafana v9.0, the envelopeEncryption feature toggle will need to be enabled to keep backwards compatibility (only from v8.3.x a bit unstable, from 8.5.x stable).

  • As a final attempt to deal with issues related with the aforementioned situations, the grafana-cli admin secrets-migration rollback command has been designed to move back all the Grafana secrets encrypted with envelope encryption to legacy encryption. So, after running that command it should be safe to disable envelope encryption and/or roll back to a previous version of Grafana.

  • Alternatively or complementarily to all the points above, backing up the Grafana database before updating could be a good idea to prevent disasters (although the risk of getting some secrets corrupted only applies to those updates/created with after updating to Grafana v9.0). Issue #49301

  • According to the dynamic labels documentation, you can use up to five dynamic values per label. There’s currently no such restriction in the alias pattern system, so if more than 5 patterns are being used the GetMetricData API will return an error.

  • Dynamic labels only allow ${LABEL} to be used once per query. There’s no such restriction in the alias pattern system, so in case more than 1 is being used the GetMetricData API will return an error.

  • When no alias is provided by the user, Grafana will no longer fallback with custom rules for naming the legend.

  • In case a search expression is being used and no data is returned, Grafana will no longer expand dimension values, for instance when using a multi-valued template variable or star wildcard * in the dimension value field. Ref

  • Time series might be displayed in a different order. Using for example the dynamic label ${PROP('MetricName')}, might have the consequence that the time series are returned in a different order compared to when the alias pattern {{metric}} is used

Issue #49173

In Elasticsearch, browser access mode was deprecated in grafana 7.4.0 and removed in 9.0.0. If you used this mode, please switch to server access mode on the datasource configuration page. Issue #49014

Environment variables passed from Grafana to external Azure plugins have been renamed:


There are no known plugins which were relying on these variables. Moving forward plugins should read Azure settings only via Grafana Azure SDK which properly handles old and new environment variables. Issue #48954

Removes support for for ElasticSearch versions after their end-of-life, currently versions < 7.10.0. To continue to use ElasticSearch data source, upgrade ElasticSearch to version 7.10.0+. Issue #48715

Application Insights and Insight Analytics queries in Azure Monitor were deprecated in Grafana 8.0 and finally removed in 9.0. Deprecated queries will no longer be executed. Please refer to the documentation for more information about this change.

Issue #48328

grafana/ui: Button now specifies a default type=“button”

The Button component provided by @grafana/ui now specifies a default type="button" when no type is provided. In previous versions, if the attribute was not specified for buttons associated with a <form> the default value was submit per the specification

You can preserve the old behavior by explicitly setting the type attribute: <Button type="submit" />

Github Issue #41863. Issue #48183

The Rename by regex transformation has been improved to allow global patterns of the form /<stringToReplace>/g. Depending on the regex match used, this may cause some transformations to behave slightly differently. You can guarantee the same behaviour as before by wrapping the match string in forward slashes (/), e.g. (.*) would become /(.*)/ Issue #48179

<Select /> menus will now portal to the document body by default. This is to give more consistent behaviour when positioning and overlaying. If you were setting menuShouldPortal={true} before you can safely remove that prop and behaviour will be the same. If you weren’t explicitly setting that prop, there should be no visible changes in behaviour but your tests may need updating. Please see the original PR ( for migration guides. If you were setting menuShouldPortal={false} this will continue to prevent the menu from portalling.

Issue #48176

Grafana alerting endpoint prefixed with api/v1/rule/test that tests a rule against a Corte/Loki data source now expects the data source UID as a path parameter instead of the data source numeric identifier. Issue #48070

Grafana alerting endpoints prefixed with api/prometheus/ that proxy requests to a Cortex/Loki data source now expect the data source UID as a path parameter instead of the data source numeric identifier. Issue #48052

Grafana alerting endpoints prefixed with api/ruler/ that proxy requests to a Cortex/Loki data source now expect the data source UID as a path parameter instead of the data source numeric identifier. Issue #48046

Grafana alerting endpoints prefixed with api/alertmanager/ that proxy requests to an Alertmanager now expect the data source UID as a path parameter instead of the data source numeric identifier. Issue #47978

The format of log messages have been updated, lvl is now level and erorand dbug has been replaced with error and debug. The precision of timestamps has been increased. To smooth the transition, it is possible to opt-out of the new log format by enabling the feature toggle oldlog. This option will be removed in a future minor release. Issue #47584

In the Loki data source, the dataframe format used to represent Loki logs-data has been changed to a more efficient format. The query-result is represented by a single dataframe with a “labels” column, instead of the separate dataframes for every labels-value. When displaying such data in explore, or in a logs-panel in the dashboard will continue to work without changes, but if the data was loaded into a different dashboard-panel, or Transforms were used, adjustments may be necessary. For example, if you used the “labels to fields” transformation with the logs data, please switch to the “extract fields” transformation. Issue #47153


setExploreQueryField, setExploreMetricsQueryField and setExploreLogsQueryField are now deprecated and will be removed in a future release. If you need to set a different query editor for Explore, conditionally render based on in your regular query editor. Please refer to for more information. Issue #48701

Plugin development fixes & changes