Skip to content
Control Plane Labs

507 Insufficient Storage

Server error response defined by RFC 4918 §11.5.

Last updated July 27, 2026

Common causes at a glance

  • Disk or volume backing the WebDAV collection is full
  • Per-user or per-collection quota exceeded by the write
  • Inode exhaustion on a filesystem that still has free space
  • A non-WebDAV application borrowing 507 to signal its own storage limit

Reproduce it

curl -i -X PUT --data-binary @big.iso https://dav.example.com/files/big.iso

What 507 Insufficient Storage means

507 covers the case where the server understood the request perfectly and simply has nowhere to put the bytes. Two situations produce it. Physical exhaustion: the filesystem or object store backing the collection is full, or out of inodes. Quota exhaustion: the user or collection has a configured limit and this write would exceed it, even though the volume has plenty of room.

Those need different responses, and the status code does not distinguish them. A full volume affects every user; a hit quota affects one account and is arguably working as designed. WebDAV servers implementing quotas expose them as live properties, so a client can find out which case it is in. Note that 507 is about server-side storage, not the request being too large to accept, which is 413.

What the spec says

RFC 4918 §11.5 defines 507: the method could not be performed because the server is unable to store the representation needed to complete the request successfully, and the condition is considered temporary. The same document lists it as a possible outcome of PUT, COPY, MOVE, and MKCOL among others. Quotas are specified separately in RFC 4331, which adds the DAV:quota-available-bytes and DAV:quota-used-bytes live properties. Nothing in HTTP core defines 507, so plain HTTP servers that emit it are borrowing the code — reasonable, but unspecified.

What actually causes it

The instructive failure is inode exhaustion, because df -h shows plenty of free space while every write fails. A collection full of tiny files — thumbnails, per-request logs, session blobs — hits the inode limit long before the byte limit, and only df -i shows it. The other recurring cause is temporary files: an upload that streams to a scratch directory needs free space equal to the payload before it lands in its final location, so a volume at 95 percent can fail a write that would otherwise fit. Quota-driven 507s are usually correct, though they surprise clients that never read the quota properties.

How to debug it

Ask the server how much room it thinks it has before assuming the disk is full. WebDAV exposes the quota properties over PROPFIND:

curl -sS -X PROPFIND -H 'Depth: 0' -H 'Content-Type: application/xml' \
--data '<?xml version="1.0"?><propfind xmlns="DAV:"><prop><quota-available-bytes/></prop></propfind>' \
https://dav.example.com/files/

If quota-available-bytes is comfortably large, the problem is the volume, not the account. On the server, check both df -h and df -i: free space with zero free inodes produces identical symptoms and gets missed constantly. Check the scratch directory separately, since it is often a different mount and fills first. If a non-WebDAV API returns 507, read its documentation — HTTP core assigns the code no meaning.

Working examples

curl

# Ask for the quota properties before blaming the disk.
curl -sS -X PROPFIND -H 'Depth: 0' -H 'Content-Type: application/xml' \
  --data '<?xml version="1.0"?><propfind xmlns="DAV:"><prop><quota-available-bytes/><quota-used-bytes/></prop></propfind>' \
  https://dav.example.com/files/

# Then attempt the write and read the status.
curl -sS -o /dev/null -w '%{http_code}\n' -X PUT \
  --data-binary @big.iso https://dav.example.com/files/big.iso

Python (requests)

import requests

QUOTA = (
    '<?xml version="1.0"?><propfind xmlns="DAV:"><prop>'
    "<quota-available-bytes/><quota-used-bytes/></prop></propfind>"
)

info = requests.request(
    "PROPFIND",
    "https://dav.example.com/files/",
    headers={"Depth": "0", "Content-Type": "application/xml"},
    data=QUOTA,
    timeout=15,
)
print(info.status_code, info.text)

with open("big.iso", "rb") as fh:
    put = requests.put("https://dav.example.com/files/big.iso", data=fh, timeout=300)
print(put.status_code)  # 507 means the server has nowhere to put it

Node (fetch)

import { openAsBlob } from "node:fs";

const quota = await fetch("https://dav.example.com/files/", {
  method: "PROPFIND",
  headers: { Depth: "0", "Content-Type": "application/xml" },
  body: '<?xml version="1.0"?><propfind xmlns="DAV:"><prop>' +
    "<quota-available-bytes/><quota-used-bytes/></prop></propfind>",
});
console.log(quota.status, await quota.text());

const put = await fetch("https://dav.example.com/files/big.iso", {
  method: "PUT",
  body: await openAsBlob("big.iso"),
});
if (put.status === 507) console.error("server storage or quota exhausted");

Reference and tooling

The authoritative list of assigned status codes is theIANA HTTP Status Code Registry. For a searchable copy with the semantics summarised, use theHTTP status code reference on this site. To see exactly what a server is sending, theheader inspector shows the raw status line and response headers, and thecurl builder assembles the request flags for you.

Other 5xx codes