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.
Requirements
- SQL Server 2016 or later on every replica. Microsoft only supports adding the SSRS catalog databases to an AG from SQL Server 2016 onward.
- Native mode SSRS (not SharePoint-integrated mode; that mode has its own HA story through SharePoint).
- Every report server that will connect to the AG-hosted catalog must be the same SSRS version and edition (and ideally the same cumulative update level).
- A working AG listener with a DNS name the report server connection string can target, so failover is transparent to the report server's connection.
- The
ReportServerservice account needs its normal database permissions granted on every replica that could become primary, not just the current primary.
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.
- Back up the encryption key first. In Reporting Services Configuration Manager, on the primary report server: Encryption Keys → Backup. Store the
.snkfile (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. - Create/confirm the
ReportServerandReportServerTempDBdatabases on the primary replica inFULLrecovery model, and take a full backup of each (required before either can join an AG). - 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. - 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.
- 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."
- 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.
Common Gotchas
- Mismatched SSRS versions across report server nodes. The catalog schema is version-specific. If one report server is a cumulative update behind, it may refuse to start against a catalog another node already upgraded.
- Forgetting the encryption key on a secondary-facing report server. The database fails over fine; the report server that never had the key restored onto it starts throwing decryption errors for every stored credential and connection string the moment it talks to the (now migrated) catalog.
- Firewall/SPN gaps to the listener. If Kerberos or the listener's port isn't reachable from every report server node, failover "works" at the SQL layer but the report server can't reconnect.
- Read-only routing. Don't route report server traffic to a readable secondary, the catalog is written to constantly (execution history, cache, session state). Point it only at the primary via the listener.
- Backups still needed. An AG is not a backup strategy. Keep taking full/log backups of
ReportServerandReportServerTempDBindependently of AG synchronization.
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.