How to fix Azure: Database is read-only during maintenance in PostgreSQL
Azure Database for PostgreSQL enters read-only mode during planned maintenance to minimize downtime. This occurs when a HA failover transitions the standby to primary or when storage reaches critical thresholds. Applications attempting write operations receive "ERROR: cannot execute INSERT/UPDATE/DELETE in a read-only transaction".
Quick fix
Fixes Azure: Database is read-only during maintenance
# Check storage via psql if you can connect
SELECT pg_database_size('your_database') as size_bytes;
# Convert to GiB (divide by 1073741824)- Check Azure Portal for maintenance status
- Verify storage is not at critical threshold
- Increase storage capacity if at threshold
- Update connection strings to use FQDN instead of IP
# Check storage via psql if you can connectSELECT pg_database_size('your_database') as size_bytes;# Convert to GiB (divide by 1073741824)Azure: Database is read-only during maintenance
What this error means
When Azure Database for PostgreSQL enters read-only mode during maintenance, it means your database temporarily cannot accept write operations. This happens for two main reasons: (1) During scheduled HA maintenance, the standby replica is promoted to primary while maintenance is applied to the old primary, or (2) Storage usage exceeds 95% of the allocated capacity, triggering automatic read-only mode to prevent disk-full errors. Your application can still read data, but INSERT, UPDATE, DELETE, and DDL operations will fail until the maintenance completes or the condition is resolved.
Typical symptoms
- Applications receive "ERROR: cannot execute INSERT in a read-only transaction" errors
- Intermittent write failures during Azure maintenance windows
- UPDATE and DELETE operations fail with read-only transaction errors
- DDL operations (CREATE TABLE, ALTER TABLE) fail during maintenance
- Application logs show connection success but transaction errors immediately after
- Issue resolves itself after maintenance window completes (typically 1-2 minutes)
- Storage-related read-only: disk space warnings in Azure Portal before write failures
Common causes
- Planned maintenance is running and HA failover is promoting standby to primary
- Storage usage has exceeded 95% of allocated capacity, triggering automatic read-only mode
- DNS configuration routes old connection to read-only secondary instance after failover
- Hardcoded IP addresses in connection strings instead of FQDN causing stale connections
- Private DNS records not updated after failover to point to new primary IP
- Replication slots are accumulating WAL files, causing storage to fill up
- Insufficient monitoring and alerting for approaching storage limits
How to fix "Azure: Database is read-only during maintenance"
Verify that maintenance is actually running during the error occurrence:
1. Open your Azure Database for PostgreSQL resource in the Azure Portal
2. Go to "Maintenance + updates" section
3. Check if "Scheduled maintenance" shows a current or upcoming maintenance window
4. Check the "High Availability" section for failover status
5. Look for notifications about ongoing maintenance (blue information banners)
If maintenance is running, the database will return to read-write mode automatically when maintenance completes (typically 1-2 minutes for HA failover). No action is required except to retry your application.
Check if storage usage triggered read-only mode:
1. Go to the "Metrics" section in Azure Portal
2. Look for "Storage used" metric
3. If storage is above 95% or available capacity is below 5 GiB, this triggered read-only mode
4. You must increase storage to restore read-write access (not automatic)
# Check storage via psql if you can connect
SELECT pg_database_size('your_database') as size_bytes;
# Convert to GiB (divide by 1073741824)If storage is the cause, proceed to Step 3. Otherwise, if maintenance is running, wait for it to complete.
If storage usage exceeded 95%, you must increase the allocated storage:
1. In Azure Portal, go to "Compute + storage" settings
2. Increase the "Storage" value (in GiB) to a higher amount
3. Click "Save" to apply the change
4. Storage increase is online and requires no downtime (unless crossing 4 TiB limit)
5. The server will automatically return to read-write mode
Storage scaling typically takes a few minutes to complete. Monitor the "Notifications" section to confirm the operation succeeded.
To calculate required storage:
- Add 20-30% buffer to current usage
- If currently at 95% of 100 GiB, increase to at least 150 GiB
- Enable "Storage autogrow" to prevent future occurrences
If the error persists after maintenance completes, DNS configuration may be stale. Update connections to use the fully qualified domain name instead of hardcoded IPs:
Bad (hardcoded IP):
const connectionString = "postgresql://user:pass@10.5.2.15:5432/db";Good (FQDN):
const connectionString = "postgresql://user:pass@myserver.postgres.database.azure.com:5432/db";FQDN allows Azure to automatically route to the current primary instance after failover. Your server FQDN is shown in the Azure Portal under "Server name" (format: <servername>.postgres.database.azure.com).
Update connections in:
- Application environment variables
- Connection pooler configuration (PgBouncer, pgpool2)
- ORM connection strings (Prisma, SQLAlchemy, etc.)
- Direct database client code
Confirm that your application network correctly resolves the FQDN to the primary IP:
# From application container/machine
nslookup myserver.postgres.database.azure.com
host myserver.postgres.database.azure.com
dig myserver.postgres.database.azure.com
# For private DNS zones (if using)
nslookup myserver.postgres.database.azure.com # from private networkExpected result: Should resolve to the primary server's current IP address. If using a private DNS zone, verify the A record points to the correct primary IP.
If DNS is cached or stale:
- Clear DNS cache on application server: ipconfig /flushdns (Windows) or restart networking (Linux)
- Update TTL in private DNS zone to 300 seconds or lower for faster failover recovery
- Check firewall/NSG rules to ensure outbound DNS queries succeed
Add resilience to your application to automatically retry failed transactions:
async function executeWithRetry(
operation: () => Promise<void>,
maxRetries = 3
): Promise<void> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
await operation();
return;
} catch (error: any) {
// Check for read-only transaction errors
if (
error.code === '25006' || // read-only SQL transaction
error.message?.includes('read-only transaction')
) {
if (attempt === maxRetries - 1) throw error;
// Exponential backoff: 1s, 2s, 4s
const delayMs = Math.pow(2, attempt) * 1000;
await new Promise(r => setTimeout(r, delayMs));
continue;
}
throw error; // Different error, fail immediately
}
}
}
// Usage
await executeWithRetry(async () => {
await prisma.user.create({ data: { name: 'Alice' } });
});This handles brief maintenance windows automatically without user intervention.
Configure Azure Alerts to notify you before storage reaches critical levels:
1. In Azure Portal, go to "Alerts" section
2. Create alert rule with conditions:
- Metric: "Storage used" or "Storage percent"
- Condition: Greater than 80% (for early warning)
- Action: Email notification
3. Create second alert for 90% to escalate urgency
4. Enable "Storage autogrow" in "Compute + storage" settings
PowerShell command:
New-AzMetricAlertRuleV2 -Name "PG-Storage-80pct" `
-ResourceGroupName "mygroup" `
-TargetResourceName "myserver" `
-MetricName "storage_percent" `
-Operator "GreaterThan" `
-Threshold 80 `
-WindowSize "PT5M" `
-Frequency "PT1M"With proper monitoring and autogrow enabled, you can prevent storage-triggered read-only mode from happening in production.
Advanced notes
Important distinction: Azure PostgreSQL read-only mode during maintenance is EXPECTED and TEMPORARY (typically 1-2 minutes for HA failover). This differs from permanent read-only mode caused by storage overflow. Always check the Azure Portal maintenance schedule before troubleshooting. If read-only persists beyond 5 minutes and no maintenance is running, storage is likely the issue. For private endpoints and private DNS zones, manually update A records post-failover since Azure does not automatically update customer-managed DNS. High Availability (HA) failovers happen during: (1) planned maintenance, (2) unplanned server failures. With HA enabled, zero-downtime maintenance is achieved by promoting the standby replica while the primary is serviced. The DNS FQDN ensures you always connect to the current primary after automatic failover. For applications with strict uptime requirements, implement connection pooling with automatic reconnection (PgBouncer, pgpool2) to quickly recover connections after maintenance.
Frequently asked questions
- What does "Azure: Database is read-only during maintenance" mean?
- When Azure Database for PostgreSQL enters read-only mode during maintenance, it means your database temporarily cannot accept write operations. This happens for two main reasons: (1) During scheduled HA maintenance, the standby replica is promoted to primary while maintenance is applied to the old primary, or (2) Storage usage exceeds 95% of the allocated capacity, triggering automatic read-only mode to prevent disk-full errors. Your application can still read data, but INSERT, UPDATE, DELETE, and DDL operations will fail until the maintenance completes or the condition is resolved.
- How do I fix "Azure: Database is read-only during maintenance"?
- Azure Database for PostgreSQL enters read-only mode during planned maintenance to minimize downtime. This occurs when a HA failover transitions the standby to primary or when storage reaches critical thresholds. Applications attempting write operations receive "ERROR: cannot execute INSERT/UPDATE/DELETE in a read-only transaction".
- What causes "Azure: Database is read-only during maintenance"?
- Planned maintenance is running and HA failover is promoting standby to primary Storage usage has exceeded 95% of allocated capacity, triggering automatic read-only mode DNS configuration routes old connection to read-only secondary instance after failover
- Is the "Azure: Database is read-only during maintenance" error serious?
- It is a medium-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐PostgreSQL Official Documentation
- ๐Azure - Scheduled Maintenance for PostgreSQL Flexible Server(Official Docs)
- ๐Azure - Business Continuity Overview(Official Docs)
- ๐
- ๐PostgreSQL - Error Codes(Official Docs)