↑↓ select↵ open⌫ change scopeOpen full search

PG.CENTER connects PostgreSQL documentation, reference, and ecosystem knowledge. Maintained by Pigsty.

Wiki / SQLSTATE

58030 — io_error

58030 is emitted by a specific shared-buffer cleanup path after a write failure has already been recorded. In PostgreSQL 18.6 that path reports WARNING, not a generic client ERROR: it names the block and relation and says that repeated failure may be permanent.

English manual coverage begins with PostgreSQL 8.1. Source history and runtime observations have their own recorded version boundaries.

Reading PG 18·Select a recorded version

aliases
Unknown
class name
System Error (errors external to PostgreSQL itself)
condition name
io_error
lang
en
sqlstate
58030

Definition PG 18

58030

At a glance {#at-a-glance}

58030 is emitted by a specific shared-buffer cleanup path after a write failure has already been recorded. In PostgreSQL 18.6 that path reports WARNING, not a generic client ERROR: it names the block and relation and says that repeated failure may be permanent.

Meaning {#meaning}

FlushBuffer starts the shared-buffer write, flushes WAL first for permanent relations, and calls smgrwrite. If error unwinding reaches the resource-owner buffer-I/O callback, AbortBufferIO marks the buffer with BM_IO_ERROR. When the buffer is still valid and dirty and this is not the first failure, it emits SQLSTATE 58030 at WARNING level, then terminates the buffer I/O with the error flag. The earlier smgrwrite failure is the event that may have aborted the client statement; this later warning is a repeat-failure notice and does not by itself establish that the client transaction is in error.

The relation text is generated from the buffer tag (relpathperm), while the write callback can add the context writing block %u of relation "%s" to the original error. The message therefore identifies where to investigate, but it is not a promise that the block is the only damaged object.

A separate storage-manager path extends a relation segment with FileWrite. If that call returns a negative result, md.c raises ERROR with could not extend file "%s": %m and errcode_for_file_access(); the saved EIO errno maps to 58030, while ENOSPC maps to 53100. This original ERROR can abort a client statement and put an explicit transaction in the failed state. It is a different emission from the later repeated-failure WARNING in AbortBufferIO.

Messages {#messages}

  • WARNING, SQLSTATE 58030: could not write block %u of %s
    • Detail: Multiple failures --- write error might be permanent.
  • Error context used around shared-buffer writes: writing block %u of relation "%s".
  • ERROR, SQLSTATE selected by errcode_for_file_access(); for saved EIO, 58030: could not extend file "%s": %m
    • Hint: Check free disk space.

The first write failure can have a different primary message and SQLSTATE, for example one selected by an OS errno helper. Preserve that first record together with this warning. In the relation-extension path, EIO deliberately selects this condition, whereas ENOSPC selects 53100; do not collapse those errno branches into a generic disk-full diagnosis.

Diagnosis {#diagnosis}

Keep the complete error chain, including the first write error, this warning, server-log context, relation fork and block, filesystem or device errno, mount state, and whether WAL or a replica has confirmed the write. Check whether the failing operation was a backend statement, checkpoint, background writer, or another server path. A source-only review cannot identify which storage component failed on a particular deployment.

Response {#response}

Stop retrying while the storage path is unhealthy. Verify the mount, device, permissions, space and quota, and storage error logs; preserve the affected relation and replica evidence before any repair. The relation-extension ERROR can leave an explicit client transaction failed, so issue ROLLBACK or ROLLBACK TO an already-established savepoint before sending more SQL. The repeated-failure WARNING from a background or cleanup path does not by itself require a client rollback, but it still requires storage remediation and a durability check. Retry the whole idempotent unit only after the cause is fixed; if the backend or server stopped, use a new connection and validate commit state before replaying work.

Versions {#versions}

The locked catalogue records this condition from 7.4; the fixed mechanism and message role are read from PostgreSQL 18.6. No natural I/O failure was induced for this source-only entry.

Related {#related}

53100, 58P03, XX001

Sources {#sources}

src/backend/storage/buffer/bufmgr.c#L4307-L4436

src/backend/storage/buffer/bufmgr.c#L6164-L6225

src/backend/storage/smgr/md.c#L512-L519

src/backend/utils/error/elog.c#L867-L942

The structured evidence record records the fixed warning, detail, source boundary, and lack of natural runtime evidence.

Compare versions

SQLSTATE evidence and recorded runtime versions

claims · identity
{
  "claim_id": "identity",
  "limits": "",
  "method": "Read locked definition snapshot.",
  "position": 0,
  "runtime": [],
  "sources": [
    "src.errcodes.18.6"
  ],
  "statement": "58030 is io_error in SQLSTATE Class 58."
}
claims · resolved-paths
{
  "claim_id": "resolved-paths",
  "limits": "Source confirmation is not natural runtime.",
  "method": "Read the complete fixed write and error-unwind contexts.",
  "position": 1,
  "runtime": [],
  "sources": [
    "src.path.0",
    "src.path.1"
  ],
  "statement": "FlushBuffer writes a shared buffer through smgrwrite, and AbortBufferIO emits the fixed 58030 warning only after a prior I/O error is present on a valid dirty buffer."
}
claims · relation-extension-errno
{
  "claim_id": "relation-extension-errno",
  "limits": "The source establishes message roles and code mapping, not a natural I/O failure on a host.",
  "method": "Read the complete negative-write branch and the saved-errno switch.",
  "position": 2,
  "runtime": [],
  "sources": [
    "src.path.2",
    "src.path.3"
  ],
  "statement": "The relation-extension FileWrite path emits ERROR with a %m primary and errcode_for_file_access(); saved EIO maps to 58030 and saved ENOSPC maps to 53100."
}
claims · history
{
  "claim_id": "history",
  "limits": "",
  "method": "Use locked catalogue boundary.",
  "position": 3,
  "runtime": [],
  "sources": [
    "src.errcodes.18.6"
  ],
  "statement": "The locked catalogue records 58030 from 7.4; it does not prove the exact introduction or every historical emitter."
}
messages · message.0
{
  "limits": "",
  "message_id": "message.0",
  "path": "",
  "position": 0,
  "raw": {
    "context_template": "writing block %u of relation \"%s\"",
    "detail_template": "Multiple failures --- write error might be permanent.",
    "id": "message.0",
    "primary_template": "could not write block %u of %s",
    "severity_source": "WARNING",
    "sources": [
      "src.path.0",
      "src.path.1"
    ],
    "sqlstate": "58030"
  },
  "severity": "WARNING",
  "sources": [
    "src.path.0",
    "src.path.1"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "could not write block of",
      "position": 0,
      "role": "",
      "template": "could not write block %u of %s"
    },
    {
      "kind": "detail",
      "literal": "Multiple failures --- write error might be permanent.",
      "position": 1,
      "role": "",
      "template": "Multiple failures --- write error might be permanent."
    },
    {
      "kind": "context",
      "literal": "writing block of relation \" \"",
      "position": 2,
      "role": "",
      "template": "writing block %u of relation \"%s\""
    }
  ]
}
messages · message.1
{
  "limits": "",
  "message_id": "message.1",
  "path": "",
  "position": 1,
  "raw": {
    "code_selection": "errcode_for_file_access()",
    "errno_condition": "saved errno EIO",
    "hint_template": "Check free disk space.",
    "id": "message.1",
    "primary_template": "could not extend file \"%s\": %m",
    "severity_source": "ERROR",
    "sources": [
      "src.path.2"
    ],
    "sqlstate": "58030"
  },
  "severity": "ERROR",
  "sources": [
    "src.path.2"
  ],
  "templates": [
    {
      "kind": "primary",
      "literal": "could not extend file \" \":",
      "position": 0,
      "role": "",
      "template": "could not extend file \"%s\": %m"
    },
    {
      "kind": "hint",
      "literal": "Check free disk space.",
      "position": 1,
      "role": "",
      "template": "Check free disk space."
    }
  ]
}
sources · src.errcodes.18.6
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/utils/errcodes.txt",
  "position": 0,
  "sha256": "6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba",
  "source_id": "src.errcodes.18.6",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt#L445"
}
sources · src.path.0
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/storage/buffer/bufmgr.c",
  "position": 1,
  "sha256": "453528ad5ab1bf8b7190ed9f866b934646278e06d802de9e5c25b6b807fcda23",
  "source_id": "src.path.0",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/storage/buffer/bufmgr.c#L4307"
}
sources · src.path.1
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/storage/buffer/bufmgr.c",
  "position": 2,
  "sha256": "453528ad5ab1bf8b7190ed9f866b934646278e06d802de9e5c25b6b807fcda23",
  "source_id": "src.path.1",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/storage/buffer/bufmgr.c#L6164"
}
sources · src.path.2
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/storage/smgr/md.c",
  "position": 3,
  "sha256": "c7e885c50b381337b8b8624bfc8effbd3abba7aa95a290083996354926ec9f69",
  "source_id": "src.path.2",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/storage/smgr/md.c#L512"
}
sources · src.path.3
{
  "commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
  "docs_url": "",
  "kind": "upstream_source",
  "location": "",
  "path": "src/backend/utils/error/elog.c",
  "position": 4,
  "sha256": "766d30a426ba1d9597657bd46fb890da3e37e4ae53a83d1245bf082ed9433c33",
  "source_id": "src.path.3",
  "tag": "REL_18_6",
  "url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/error/elog.c#L867"
}

Source references

Full definition and evidence JSON

Definition sources

center · PostgreSQL 18 · english-manuals:33c9cdf2d83c07adaaa7ae95ddeaf54c606cda334ae29330761bf41fb6b44031

Text language: en · english-manuals:33c9cdf2d83c07adaaa7ae95ddeaf54c606cda334ae29330761bf41fb6b44031