powershelldba.de · Uwe Janke

SQL Server Reporting Services (SSRS) on AlwaysOn Availability Groups

How to make SSRS highly available by moving the ReportServer and ReportServerTempDB catalog databases into an AlwaysOn Availability Group: requirements, encryption key handling, and failover behavior.

SQL Server Reporting Services has no built-in high availability of its own. The report server is a stateless-looking web service, but its actual state, reports, data sources, subscriptions, execution history, cached snapshots, lives entirely in two SQL Server databases: ReportServer and ReportServerTempDB. If those databases go down, SSRS goes down with them, regardless of how many report server nodes you have running. Putting those two databases in an AlwaysOn Availability Group is how you close that gap.

Two Different HA Models, Don't Mix Them Up

SSRS has long supported a scale-out deployment: multiple report server instances pointing at one shared catalog database, load-balanced behind a URL. That solves availability of the web/rendering tier, but the catalog database itself is still a single point of failure unless it sits on a failover cluster instance or, since SQL Server 2016, in an Availability Group.

Layer What can fail What protects it
Report server service (web/rendering tier) IIS/report server node crash, patching, reboot Scale-out deployment behind a load balancer or NLB
Catalog databases (ReportServer / ReportServerTempDB) SQL Server instance/host failure AlwaysOn Availability Group (this article)

This article is about the second row. You still need a scale-out (or at minimum a second report server pointing at the same catalog) if you also want the web tier itself to survive a node loss; the AG only protects the data.

Architecture at a Glance

Two independent layers, each with its own failure domain: the report server nodes in front (scale-out, stateless), and the catalog databases behind them (AG-protected, stateful). Only the listener name connects them.

https://reports.company.com Report Server A web / rendering tier Report Server B web / rendering tier scale-out deployment, load-balanced AG Listener (DNS name) AVAILABILITY GROUP (WSFC) re-resolves here on failover Primary Replica ReportServer ReportServerTempDB read / write Secondary Replica ReportServer ReportServerTempDB not readable by SSRS sync
Encryption keys don't live in the AG. They're machine-level material on each report server node, not part of the replicated database. That's why the diagram's two report server boxes each need their own key restore (step 5 below), even though there's only one catalog behind them.

Requirements

ReportServerTempDB is not tempdb. It behaves like a regular user database (it just holds session, cache, and working-set data), so it replicates through the AG like any other database. Don't confuse it with the instance's system tempdb, which can never be AG-protected.

Configuration Sequence

The order matters. Doing this out of sequence is the most common way people end up with a report server that starts, shows the "Reporting Services Configuration Manager" green checkmarks, and still throws rsReportServerDatabaseUnavailable the moment someone opens a report.

  1. Back up the encryption key first. In Reporting Services Configuration Manager, on the primary report server: Encryption Keys → Backup. Store the .snk file (and its password) somewhere safe, off the SQL Server. Every credential, connection string password, and stored value in the catalog is encrypted with this key; without it, a restored or failed-over catalog is unreadable.
  2. Create/confirm the ReportServer and ReportServerTempDB databases on the primary replica in FULL recovery model, and take a full backup of each (required before either can join an AG).
  3. Add both databases to the Availability Group, the same way you would any other database: join on the primary, seed (or manually restore with NORECOVERY) on every secondary, then join.
  4. Point each report server's connection string at the AG listener name, not the underlying instance name. In Reporting Services Configuration Manager → Database, change the server name to the listener's DNS name and re-run the connection wizard so it re-validates against the listener.
  5. Restore the encryption key from step 1 onto every report server node that will use this catalog (Encryption Keys → Restore). Each report server instance has its own machine-level key material even though they share one catalog; skipping this step is the single most common cause of "it deploys fine but every subscription/data source with saved credentials breaks."
  6. Restart the SQL Server Reporting Services service on each node after the connection string change, then verify with a report that uses a stored (not prompted) credential, that's the check that actually proves the encryption key round-tripped correctly.

What Happens on Failover

When the AG fails over, the listener re-resolves to the new primary and SQL connections reconnect automatically, same as with any other AG-protected application. From the report server's point of view this looks like a transient connection error: in-flight report executions fail, but the report server retries its next database call against the listener and picks the new primary back up without any manual reconfiguration, provided the connection string was set to the listener name and not a specific instance.

Quick sanity check after setup: Manually fail the AG over once during a maintenance window and confirm subscriptions still fire, cached report execution still works, and a report using a stored data source credential still renders, before you trust this in production.

Common Gotchas

Monitoring Once It's Running

Once the catalog databases are AG-protected, keep an eye on the report server side too, execution history, subscription failures, and cache/snapshot health don't show up in AG dashboards. A diagnostic report suite like ReportServerCheck queries the ReportServer catalog directly for execution trends, subscription delivery status, and data source health, which is exactly the layer an AG failover won't tell you about.

The Bottom Line

Putting SSRS on an Availability Group is straightforward T-SQL-wise, it's the same ALTER AVAILABILITY GROUP ... ADD DATABASE you'd run for any other database. The part that actually takes care is everything around it: matching SSRS versions on every node, pointing every connection string at the listener instead of an instance name, and restoring the encryption key onto every node that will ever serve that catalog. Get those three right and failover becomes boring, which is exactly the point.