How to fix I/O error in PostgreSQL

PostgreSQLINTERMEDIATEHIGHUpdated Dec 28, 2025· 273 views

PostgreSQL I/O errors occur when the database cannot read or write data to disk, typically due to network issues, disk space problems, or hardware failures. Diagnosis involves checking connectivity, disk space, and PostgreSQL logs.

Quick fix

Fixes I/O error

df -h /var/lib/postgresql/data
df -h /var/lib/postgresql/data/pg_wal
  1. Verify disk space availability
  2. Check PostgreSQL logs for specific error details
  3. Verify network connectivity and firewall rules
  4. Enable TCP keepalive to prevent idle disconnections
postgresql — error
df -h /var/lib/postgresql/data
df -h /var/lib/postgresql/data/pg_wal
I/O error

What this error means

An I/O error in PostgreSQL indicates a failure in input/output operations at the system level. This can manifest in several ways: as "An I/O error occurred while sending to the backend" (a JDBC driver error), as disk write failures when running out of space, or as connection drops due to network issues. The error occurs when PostgreSQL or the database client cannot communicate properly or when the database cannot access its data files on disk.

Typical symptoms

  • Application queries fail with "I/O error" messages
  • Database connections drop unexpectedly during operations
  • psql or other client tools cannot complete transactions
  • Error messages appear in PostgreSQL logs about failed disk writes
  • Firewall or timeout warnings appear in connection logs
  • Large queries fail while smaller ones succeed
  • Query execution hangs and times out after a period of inactivity

Common causes

  1. Network connectivity issues between client and PostgreSQL server, including firewalls, NAT devices, or VPN gateways that drop idle connections
  2. Socket timeout expiration when executing long-running queries or when the connection is idle
  3. Insufficient disk space on the volume holding the PostgreSQL data directory ($PGDATA) or WAL files
  4. File system full on the partition containing WAL (Write-Ahead Log) segments in pg_wal directory
  5. Hardware failures or faulty storage devices unable to complete read/write operations
  6. Database corruption preventing normal read/write access to data files
  7. Permission issues preventing PostgreSQL from accessing data files or directories
  8. Memory pressure triggering Linux OOM killer which terminates PostgreSQL processes
  9. TCP connection timeouts due to slow network or large query sizes exceeding buffer limits

How to fix "I/O error"

1Verify disk space availability

Check if your PostgreSQL data directory or WAL partition is full:

bash
df -h /var/lib/postgresql/data
df -h /var/lib/postgresql/data/pg_wal

If usage is at or near 100%, this is likely the cause. You must free up disk space before PostgreSQL can resume normal operations. Common actions:
- Remove old backup files or temporary data
- Archive log files to external storage
- Truncate large tables no longer needed

If you cannot free space, consider adding a new disk or expanding the volume via your cloud provider's management console.

2Check PostgreSQL logs for specific error details

Review PostgreSQL server logs to identify the exact I/O error:

bash
tail -f /var/log/postgresql/postgresql.log

Or query the system logs for recent PostgreSQL errors:

bash
grep -i "i/o error\|no space left\|cannot extend" /var/log/postgresql/postgresql.log

Look for patterns like:
- "ERROR: could not extend file" → disk full
- "ERROR: cannot execute" with "no space left on device" → WAL or data directory full
- Connection reset errors → network issue

3Verify network connectivity and firewall rules

Test TCP connectivity from your client to the PostgreSQL server:

bash
telnet postgres_host 5432

Or using nc (netcat):

bash
nc -zv postgres_host 5432

For firewall verification:
- Ensure the PostgreSQL port (default 5432) is not blocked
- Check stateful firewalls for connection drop rules (often drop idle connections after 15-30 minutes)
- Verify no VPN or proxy is dropping idle connections

If the connection fails, check your postgresql.conf settings:

bash
grep "^listen_addresses\|^port" /etc/postgresql/*/main/postgresql.conf
4Enable TCP keepalive to prevent idle disconnections

Configure TCP keepalive on both client and server to prevent firewalls from dropping idle connections.

On the PostgreSQL server, edit postgresql.conf:

ini
tcp_keepalives_idle = 300      # seconds before first keepalive probe
tcp_keepalives_interval = 30   # interval between probes
tcp_keepalives_count = 5       # number of probes before drop

Then reload the configuration:

bash
postgresql-ctl reload
# or
sudo systemctl reload postgresql

For JDBC connections in Java applications, add socket timeout and TCP keepalive parameters to your connection string:

bash
jdbc:postgresql://localhost:5432/database?socketTimeout=30&tcpKeepAlives=true
5Increase socket timeout for long-running queries

If queries exceed 30 seconds, increase the socket timeout to prevent premature disconnection.

In JDBC (Java), add to connection properties:

bash
jdbc:postgresql://host:5432/db?socketTimeout=60000

The value is in milliseconds. For very long operations (analytical queries), use higher values:

bash
socketTimeout=300000  # 5 minutes

For other client libraries:

Python (psycopg2):

python
import psycopg2
conn = psycopg2.connect(
    host="localhost",
    connect_timeout=10,
    options="-c statement_timeout=300000"
)

Node.js (pg):

javascript
const client = new Client({
  connectionTimeoutMillis: 10000,
  query_timeout: 300000,
});
6Run VACUUM and full maintenance if database appears corrupt

If you suspect database corruption, run maintenance operations:

bash
sudo -u postgres vacuumdb -d your_database -f

For a more thorough check:

bash
sudo -u postgres vacuumdb -d your_database -fz
sudo -u postgres analyzedb -d your_database

Caution: VACUUM FULL is resource-intensive and locks tables. Run during maintenance windows.

If you experience persistent I/O errors even after these steps, consider:
- Backing up your database
- Checking the PostgreSQL cluster with pg_check_cluster or initdb --check
- Moving the database to different hardware if a hardware fault is suspected

7Upgrade PostgreSQL JDBC driver (Java only)

If using Java applications, ensure you're running the latest PostgreSQL JDBC driver, which contains bug fixes for I/O error handling.

In your pom.xml (Maven):

xml
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.7.0</version>
</dependency>

Or in build.gradle (Gradle):

gradle
dependencies {
    implementation 'org.postgresql:postgresql:42.7.0'
}

The latest version is available at https://jdbc.postgresql.org/. Older drivers may have issues with connection timeouts or large query handling.

Advanced notes

Connection Pool Configuration: If using a connection pooling library (HikariCP, pgBouncer), ensure pool settings match your workload. Idle connections may be dropped by firewalls; consider setting idleTimeout to less than your firewall's idle connection limit. WAL Management: If pg_wal fills up, old WAL segments cannot be recycled. This often happens when archiving is enabled but the archive_command fails. Check: SELECT * FROM pg_ls_waldir(); to see accumulated WAL files. Large Queries: Very large queries (40k+ parameters) may exceed buffer limits, causing I/O errors. Reduce query size by using batch processing or CTEs. OOM Killer Protection: On Linux, the OOM killer may target PostgreSQL. Protect the postmaster process by setting oom_score_adj=-900 in your systemd service or init script. Diskless Operations: For cloud databases (RDS, Azure PostgreSQL), I/O errors may indicate the underlying storage is overprovisioned. Monitor IOPS usage and scale up if needed.

Frequently asked questions

What does "I/O error" mean?
An I/O error in PostgreSQL indicates a failure in input/output operations at the system level. This can manifest in several ways: as "An I/O error occurred while sending to the backend" (a JDBC driver error), as disk write failures when running out of space, or as connection drops due to network issues. The error occurs when PostgreSQL or the database client cannot communicate properly or when the database cannot access its data files on disk.
How do I fix "I/O error"?
PostgreSQL I/O errors occur when the database cannot read or write data to disk, typically due to network issues, disk space problems, or hardware failures. Diagnosis involves checking connectivity, disk space, and PostgreSQL logs.
What causes "I/O error"?
Network connectivity issues between client and PostgreSQL server, including firewalls, NAT devices, or VPN gateways that drop idle connections Socket timeout expiration when executing long-running queries or when the connection is idle Insufficient disk space on the volume holding the PostgreSQL data directory ($PGDATA) or WAL files
Is the "I/O error" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading