Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Errors and limits

Error shape

amber-git reports errors in two places:

  • Per ref, inside a push. git prints a refused ref update as ! [remote rejected] <ref> -> <ref> (<reason>) and exits non-zero. The other refs in the same push are decided on their own. Reasons you may see: queued for approval by the repo owner (ref <handle>), the amber-ci gate: refusals in Concepts, tags don't move: <ref> exists; ... for a push that moves a tag, and refusals of a delete, such as ref moved to <sha>; fetch and retry the delete.
  • As an HTTP status, with a plain-text body (Content-Type: text/plain; charset=utf-8), which git prints after fatal: or remote:.

Messages are written for people and may change; there are no error codes.

curl -sS https://amber-git.stackwell.tech/nope | grep -Fx 'not found'

Status codes

StatusMeaning
200Done.
202A re-send to the GitHub mirror was queued.
400A withdraw without a handle, a check of a queued push without a full sha, or an unknown service on info/refs.
401No token, or one amber-git doesn’t accept. Body unauthenticated, with WWW-Authenticate: Basic realm="amber-git" and WWW-Authenticate: Bearer.
403You can’t reach this repository, or a read-only client tried to push.
404No such path, no such repository, or one you can’t reach. Also a file the read routes can’t find (with Amber-Git-Absent: path).
409A withdraw that came too late, or a re-send for a repository that doesn’t mirror.
410The repository was renamed (repository was renamed to <name>) or retired.
413Over a size limit; see below.
422The read routes were asked for a commit no branch or tag reaches.
502A withdraw, or a check of a queued push, couldn’t reach Granite. The push stays queued; retry.
503The server is busy; retry after the Retry-After header (30 seconds).

Without a valid token, every repository answers 401, whether or not it exists:

curl -sS -o /dev/null -w '%{http_code}\n' 'https://amber-git.stackwell.tech/any-repo.git/info/refs?service=git-upload-pack' | grep -Fx 401

Rate limits and busy answers

amber-git has no per-caller rate limit. Each push, fetch, clone or file read reserves memory before it starts. When none is free, the request waits up to 60 seconds (15 seconds for the read routes) and then gets 503 with Retry-After: 30. A server out of temporary disk answers the same way.

Size limits

LimitValue
One push, on the wire2 GiB; the push is refused
One object, uncompressed100 MiB; the push is refused
Objects in one push250,000; the push is refused
One fetch or clone request body (what your client sends)10 MiB (413)
A file from the read route1 MiB (413)
A tree listing from the read route16 MiB (413)
Commit and tree data one clone or fetch may readAbout 64 MB; past it, refused with a message
Commit and tree data one push may readAbout 16 MB; past it, refused with a message

A push over 2 GiB is refused with the reason, as a rejected push: remote unpack failed: push is over 2048 MB, .... Past 4 GiB the server stops reading and answers 413. Git may show only RPC failed; curl 55 Send failure: Connection reset by peer, because it is still sending when the connection closes. Either way nothing from the push is stored.

GET /limits, with any valid token, returns the push, object and walk limits in force as JSON, so a tool can check a repository before pushing it without keeping its own copy:

{"max_push_bytes": 2147483648, "max_object_bytes": 104857600,
 "max_push_objects": 250000, "max_push_walk_bytes": 134217728,
 "max_fetch_walk_bytes": 536870912, "walk_bytes_per_object": 128,
 "walk_bytes_per_byte": 8}

A walk is charged walk_bytes_per_object for each distinct commit, tree or tag it reads, plus walk_bytes_per_byte for each byte of it.

The push and object limits match GitHub’s. A long-running push or fetch is kept alive while the server works; a client that stops sending for 5 minutes is disconnected.