Release notes
To check which version you are running:
shard versionIt prints the version of the CLI on a client line, then the version of the daemon or server it reaches on a daemon line.
To upgrade the CLI, run the installer again. To upgrade a host that setup prepared, run shard setup on it and choose to upgrade. Each release on GitHub includes the binaries and their SHA256SUMS.
shard is pre-alpha, so a release can change the API, the CLI and the SDKs without any compatibility guarantees.
Unreleased
Section titled “Unreleased”Breaking
- A sandbox is a machine, and
shard runstarts named processes in it.shard run SANDBOX [--name NAME] [--restart POLICY] [--attach] -- COMMANDstarts a process that shard-init supervises, prints its name and returns. The restart policy isno,on-failure,alwaysorunless-stopped, the default. shard run IMAGE COMMANDand-d/--detachare gone. Runshard create IMAGE, thenshard run SANDBOX -- COMMAND.shard createtakes no command and no restart flags. A new sandbox runs no process untilshard runstarts one.shard logs SANDBOX [NAME]shows the output of one process. With no name, it shows the sandbox’s only process.- The API runs processes under
/v0/sandboxes/{id}/processes. The sandbox’s/logs,/attachand/app/stoproutes are gone, a create refusescommandandrestart, and a sandbox record listsprocessesin place ofcommand,restartandexit_status. The error codesno_appandapp_endedgive way tono_processandprocess_limit, and a run of a name that still runs answersname_taken. - The SDKs follow:
sandbox.run(command)returns aProcess, andshard.run(image, command),Appand the sandbox’s ownlogs()are gone.
New
shard ps SANDBOXlists the processes of a sandbox with their state, restarts, last exit and policy.shard listcounts the processes that run in each sandbox.shard kill SANDBOX NAMEends one process and cancels its restarts, and the sandbox stays up.--forcekills it at once.shard run --attachprints the output and exits with the process’s code. Ctrl+C detaches and leaves the process running.- When the daemon starts, it starts again each sandbox that holds an
alwaysprocess, or anunless-stoppedone that neithershard stopnorshard killended, and runs those processes again. So they come back after a host reboot. shard port add SANDBOX [HOST:]GUESTforwards a host port to a port inside a sandbox, on127.0.0.1, or on0.0.0.0with--public.shard port listandshard port removelist and end the forwards, andshard create --portforwards from the first start. A forward survives a stop, a start and a daemon restart. It works on every provider, and the SDKs havesandbox.ports. See Reach a port inside a sandbox.- Two new token scopes:
port:readlists the forwards, andport:writeadds and removes them. shard capabilitiesandGET /v0/capabilitieslist a ninth verb,port.
v0.1.5
Section titled “v0.1.5”7 October 2026. Full notes.
Fixes
shard create --snapshot NAME --user USERfinds a user that the snapshot holds and the image does not. Before, the create failed withresolve the user "USER": no such entry in the image.- A sandbox created from a snapshot uses the CA bundle of the snapshot for a policy or a secret, at create and at a later
shard policy attachorshard secret grant. Before, shard read the CA bundle of the image, so it failed withimage ... has no CA bundlewhen only the snapshot hadca-certificates. - Firecracker and vz: the entrypoint and every exec get
HOMEfrom the/etc/passwdof the sandbox, as on gVisor, runc and Sysbox. Before,HOMEwas not set, so~did not expand. AHOMEthat you set with--envstill wins.
v0.1.4
Section titled “v0.1.4”6 October 2026. Full notes.
New
shard shell SANDBOXopens an interactive shell in a sandbox:bash, orshwhen the image has nobash. It takes--workdirand--user, and exits with the shell’s exit code. When the image has no shell at all, it says so.shard stop,shard remove,shard pauseandshard resumetake several sandboxes. A failure does not stop the others: the command prints each failure and exits non-zero.shard list -q(--quiet) prints only the ids. It does not go with--format.shard pruneremoves every stopped sandbox, and asks first. With no terminal, it needs--force.shard setupcan set up the HTTP API (shard serve) as a background service. A first install asks, and a new “Set up the HTTP API” row adds it to an existing install. The flags are--http-api,--listen(default127.0.0.1:7850) and--replace-api-key. Setup creates an API key and saves it in/etc/shard/api-key, which only root can read, or in/var/lib/shard/auth/api-keyon a Mac. It never prints the key. A repeated setup keeps the key, and--replace-api-keyreplaces it. With no terminal,--http-apidefaults tofalse.- Firecracker and vz: a sandbox created with no
--memory, or with--memory 0, gets 512 MiB. Before, the create failed. A fork keeps the memory of its source, and a create from a snapshot keeps the memory of the snapshot. Under 128 MiB still fails, with--memory is 100 MiB, under the 128 MiB provider firecracker needs; set it to 128 MiB or more.
Install and setup
shard setup --storage-size <size>andshard daemon --storage-size <size>set how much space shard reserves for its data. They apply only to Firecracker on a filesystem that cannot clone files, such as ext4. Elsewhere the flag fails and says why. The default is half of the free space, at most 100 GiB. The minimum is 10 GiB, and 10 GiB always stays free for the host. Setup shows the size of an existing image and never resizes it. With no terminal and no flag, setup takes the default and prints it.- On Linux, when the daemon fails at start, setup and repair stop after about 6 seconds, not 2 minutes. They print
The daemon failed to start:with the daemon’s error, thenRead its log with: sudo journalctl -u shard.service. - When a daemon task keeps failing (3 or more restarts), setup stops its wait after about 3 seconds. It prints
The daemon started, but these tasks keep failing:, then each task with its last error. - When the GitHub API rate limit for your IP address is spent, setup says so and gives the local time when it resets, or says to try again within an hour. The installer prints the reset time too. Setup now downloads its files from the release download URLs, which have no rate limit, so only the check for a newer release uses the API.
shard setupon an installation that setup did not make still changes nothing, and now exits 1, so a script can tell that refusal from a successful setup. Before, it exited 0.
Uninstall
- Uninstall removes the
shard-serveunit that setup wrote. Ashard-serveunit that you installed yourself stays. Uninstall says that a new setup does not start it, and printssudo systemctl start shard-serveand the commands that remove it. Before, the next setup after an uninstall could delete it. - On Linux, uninstall also removes the iptables rules and the firewalld zone that shard added for its bridge.
CLI
- Errors name a sandbox by its name, or by its id when it has no name.
shard inspectshowsforked_from, the id of the sandbox that a fork came from.- When a file is missing,
shard cpnames the path and the sandbox:"/missing" in sandbox sb: no such file or directory. sudo shard cpfrom a sandbox leaves the copied files owned by the user who ransudo, not by root. A directory that is already there keeps its owner and mode.- A disk that the provider refuses names
--diskand the fix. A fork cannot set its disk, so its refusal says to remove a sandbox. shard exec --workdirwith a directory that does not exist exits 126 on every provider. On every provider but gVisor, the error saysthe work directory "/missing" does not exist.
API and SDKs
- The sandbox record has a new
forked_fromfield: the id of the sandbox a fork came from. - A resume keeps
started_at, so the uptime counts from the first start. - Errors and the
in_useholder lists name a sandbox by its name, or by its id when it has none. - A failed create names its network cause, such as
set up the sandbox network on the host: nft failed: No such file or directory. Host paths and addresses stay in the daemon log. When no address is free, the error saysno free address left: every sandbox holds one until it is removed, run shard list --all and remove the ones you no longer need. - A disk that the provider refuses at create, fork or pause is a
400 invalid_requestthat names the fix, not a500 internal. - An exec with a work directory that does not exist is a
422. runc and Sysbox answered500before. - A sandbox with a secret or a policy needs an image with a CA bundle. Without one, create,
secret grantandpolicy attachanswer400 invalid_request, not500:image index.docker.io/library/node:22-bookworm-slim has no CA bundle, which a sandbox with a secret or a policy needs: use an image with ca-certificates. - When the host does not trust the certificate of an upstream, the
502from the proxy hashostandreasonin its body, such asthe upstream's certificate is signed by an authority the host does not trust.shard policy logsshows it as a deny of the rulecertificate. To trust an internal CA, add it to the host’s certificate store and restart the daemon. - In
shard policy logs, a drop by a host rule hasrule_text, as long as the rule has not changed since. - Every client and SDK gets the new text of the
cpfile errors.
Fixes
- On a host with ufw or firewalld, sandboxes got no DNS, no proxy and no routed traffic, because the host firewall dropped them first. shard now opens its bridge as Docker does: iptables rules with the comment
managed-by-shard, and a firewalld zoneshard. The daemon checks them every 5 seconds, so it repairs them after aufw reload. The docs no longer tell you to runufw allow. If firewalld already has a zoneshardor a policyshard-forwardingthat shard did not make, shard leaves that zone or policy unchanged and refuses to start a sandbox. Rename yours, or remove it if nothing uses it. - A client of the HTTP API also sees that cause: the failed reason of the sandbox names the zone or the policy.
- A second daemon on another root no longer removes the network rules of the first daemon’s sandboxes. It refuses to start:
shard: another shard daemon, over the root /var/lib/shard, already serves this host's sandbox bridge and nft table: a host runs one daemon, so stop that one or use its root. - Under the
UMask=0077that setup gives the daemon,/etcand the work directory of a sandbox were0700, so users other than root and apt failed. Directories that shard makes in a sandbox are0755now, and every exec runs with umask0022. Mount points that Sysbox makes itself still take the daemon’s umask. - Firecracker and vz: after a resume or a fork, the guest clock matches the host clock. Before, it was behind by the length of the pause, so TLS checks failed. This also holds for Firecracker on arm64, so the limits page no longer lists it.
- Firecracker and vz: a fork whose disk copy cannot fit fails before shard captures the source. The source no longer freezes and pauses for it, which took 12 to 14 seconds on Firecracker.
- Firecracker and vz: a sandbox makes its work directory at start, so
shard create --workdir /workworks. Before, every exec then failed withno such file or directory. - Firecracker and vz:
shard exec -itsends every key to the guest, so Ctrl-C, Tab, the arrow keys and Ctrl-R work, and each line no longer shows twice. The exit no longer waits 2 seconds. - Firecracker and vz: an exec of a command that no
PATHentry holds exits 127, as on gVisor. - Firecracker and vz: a stop of a fork’s source no longer fails with a lost lifecycle state when the guest closed its control stream during the thaw. shard now connects again and asks the guest whether it is still frozen.
- An exec with no
--userno longer waits 20 seconds when a process in the sandbox replaces/etc/passwdwith a fifo. gVisor refuses a/etc/passwdthat is not a regular file. On runc and Sysbox, their own init still opens the file, so such an exec can still wait up to 20 seconds. - gVisor:
shard exec --workdirwith a file exits 126 withthe work directory "/etc/hosts" is not a directory, as runc and Sysbox do. Before, the command ran. - gVisor:
shard exec -itandshard shellrun the command on a terminal in the guest, sottynames it, and Ctrl-C and job control work. Before, the command got the host’s terminal andttysaidnot a tty. On every provider, a terminal exec with noTERMnow getsTERM=xterm. - Sysbox: Docker inside a sandbox failed with
permission deniedwhen it mounted its cgroups, once a gVisor or Firecracker daemon had made/sys/fs/cgroup/shardwith mode0750. shard now makes that directory0755, and a Sysbox create or start sets an existing one back to0755.
Site
- The landing page scales with the width of a big screen.
- The landing page and every docs page have a full SEO head and an OG image. The site serves
robots.txt,sitemap.xml,llms.txtandllms-full.txt.
v0.1.3
Section titled “v0.1.3”6 October 2026. Full notes.
New
- These docs cover install and setup, a quickstart for a server and one for a client, the concepts, the security model, guides, the TypeScript and Python SDKs, a reference and help. The guides that were in the repository’s
docs/folder moved here. - The CLI and REST API reference pages are built from the CLI’s help text and the API’s routes, so they list every command, flag and endpoint of this release.
- Firecracker and vz: the
kernelfield of a sandbox names the guest kernel that it booted, such askernel-6.12.110-3, orlocal-and a hash prefix for a kernel set withSHARD_KERNEL. A fork keeps the kernel of its source. gVisor, runc and Sysbox leave the field out. shard create,shard forkandshard run --detachprintcreated sandbox <name>on stderr for a sandbox with a name. Stdout still holds only the id.
Install and setup
- With a saved remote connection,
shard setupopens on the menu of that connection: check, replace, remove, run sandboxes on this machine, or exit.--local,--provideror--start-at-bootpicks the local choice. - Setup says that a saved connection stores the API key as plain text before it asks whether to save it, not after the save.
- A local setup with no terminal names every flag that it still needs in one error, before any check, and exits 1.
- On Linux, setup also finds a Firecracker disk image in
/var/lib/shard. When the data belongs to another provider, setup prints the commands that keep or delete it. The delete steps first remove the sandboxes through a daemon of that provider, so their network and cgroups go too. Then they delete the data. With a disk image, they first unmount and remove it, with the same commands as the uninstall note. When shard is not installed yet, the steps first have you choose that provider, so setup installs shard and starts its daemon, and then uninstall shard after the sandboxes are gone. Repair and upgrade stop with the same advice before they change anything. - On Linux, when only root can read the sandbox records, setup asks for administrator access before its checks. It skips a record that it cannot read, as the daemon does.
- After a failed step, the retry hint names a command that runs:
shard setup, or the full path of the binary whenshardis not onPATH. With no terminal, the hint also repeats the flags of the run. - A menu or the step list that gets shorter no longer leaves old lines on the screen.
- The tool download shows its progress for
runsc,firecrackerandsysbox. A download that gets no data for 30 seconds fails withno data for 30s. - A local setup ends with
shard <version> is set up., and a repair withshard <version> is repaired.. When the service starts at boot, both say, and the daemon is running.instead of the period. - Setup prints
sudoonly where you need it: never before a shard command on a Mac, and never when you are logged in as root.
Uninstall
- On Linux, the note ends with the command that deletes the saved data:
sudo rm -r /var/lib/shard, and the lock file of the disk image when there is one. After thesedthat removes the/etc/fstabline, it addssystemctl daemon-reload. - On Linux, when the disk image is gone but its
/etc/fstabline stays, the note names that line and the commands that clean it up, withumountfirst while the data directory is still mounted. - On a Mac, the note also prints the command that deletes the saved data.
CLI
- When the daemon does not answer on a host where setup installed a service that starts at boot, the error says
is the background service running? shard setup repairs it. - Errors name the fix as a command or a flag. Errors and help text say API key instead of token, and write shard in lowercase. A command in a hint starts with
sudowhen you ran the CLI withsudoagainst the local daemon. shard snapshot createon a sandbox whose image is gone namesshard pull <image>, the command that exists.
API and SDKs
- A sandbox or snapshot name with the shape of a generated id gets
400 invalid_request, not500 internal. - Error messages use plain words and name the fix. Match on
code, not on the text. The texts offailed_reasonandstopped_reasonchange too. - The
useshardsSDKs 0.1.1 carry the same wording in their errors.
Fixes
- vz: when the daemon loses its connection to a guest and cannot read the VM state, the sandbox no longer shows as
stopped. The daemon tries again, then reports the error. - vz: a connection to a guest that times out no longer leaves a goroutine or a handle in the daemon.
- vz: when the process that runs a VM ends, the sandbox shows as
stopped, neverrunning. A status first waits for the daemon to record the end, for at most 10 seconds once the daemon finds the process gone. Before, it could show asrunningfor a while, and for good when the daemon had lost its connection to that process. - gVisor, runc and Sysbox: the restart count comes back with the exit record, which the host holds, so a process in the sandbox can no longer change it. A file left in
/.shardno longer makesstoporstartfail. shard rmno longer fails when the egress log writes into the sandbox directory during the remove.
Site
- The landing page has a new design, and these docs take its palette, fonts and logo.
- The installer’s banner shows the new logo.
v0.1.2
Section titled “v0.1.2”5 October 2026. Full notes.
New
- One-line install:
curl -fsSL https://useshards.com/install | shdownloads the newest release, checks it against that release’sSHA256SUMS, installs it to~/.local/bin/shard, and offers to runshard setup. The old binary stays in place until the verified new binary replaces it in one rename.
Install and setup
- The PATH hint also prints the
exportline for the current shell, soshardworks without opening a new shell. shard setup --helplists the setup exit codes.- For a user that
sudodoes not allow, the administrator check fails immediately and names the reason. A user whosesudoneeds a password passes only when setup can ask for it at a terminal. - On a Mac where no local provider can run, setup defaults to a remote connection and says why
vzis not available. The provider menu marksvzas recommended. - A local setup ends by listing the next steps. When the daemon does not start at boot, it also prints the command that runs the daemon in the foreground.
- Check or repair finds a deleted provider file. An upgrade checks that the restarted daemon answers before it reports the upgrade as done.
- A download that stalls for 30 seconds fails with
connection timed out, instead of showing a spinner for about 17 minutes. A slow download that is still making progress completes, and a failed download names its cause in plain words. - On a manual install, setup shows the install’s version and provider, and the commands that move it to setup. It leaves the install’s files unchanged.
Uninstall
- An uninstall removes the bridge and the nft tables when no sandbox or proxy still uses them, and says how to turn
ip_forwardoff. It never changesip_forwarditself. - It names what it leaves behind, with the commands that remove it: the data disk image
/var/lib/shard.xfson Linux, and the daemon logs in/var/log/shardon a Mac. - On Linux, the refusal that asks you to remove your sandboxes first prints its commands with
sudo.
Remote
- When the server refuses an API key, the error names where the key came from (
SHARD_API_KEYor the saved connection) and how to fix it. It never prints the key. - A failed connection names its cause, such as no answer, a self-signed certificate, or a socket that needs
sudo.
CLI
- When an error says the cause is in the daemon log, it names where that log is on this host.
- When shard refuses a create, the error names the flag you type, such as
--memory, rather than the API field. shard listprints on stderr how many stopped sandboxes it leaves out.shard execon a stopped sandbox refers to the sandbox by its name instead of its id.
v0.1.1
Section titled “v0.1.1”5 October 2026. Full notes.
New
shard setupprepares this host for local sandboxes, with the provider, its tools, the data directory, and a systemd or launchd service. It can also save a connection to a remote server instead.- The
useshardsSDKs 0.1.0 are on npm and PyPI. They are versioned and released separately from shard.
Fixes
- Firecracker: if a create, start, fork or restore is interrupted after its VM has come up, shard now ends that VM.
- macOS and Firecracker: for an image that another provider already pulled, the missing disk format is built offline, without a registry call. The pull streams
building, thenpulled. - macOS and Firecracker: an image already on the host with missing blobs no longer heals itself from the registry. Remove it and pull it again.
- macOS:
stopno longer fails after 10 seconds while a reconnect to the guest is still in progress. - Sysbox:
stopno longer fails when the guest removes one of its own cgroups during the stop. After a daemon restart,stopand a forced remove no longer fail on a sandbox whose first process has its standard input on a file the daemon cannot open. - runc, Sysbox and gVisor: an unreadable memory count is now an error, where before it read as no out-of-memory kill.
- Egress: each sandbox logs its dropped packets under its own rate limit, so one sandbox can no longer silence the drop records of the others.
- Egress: a request that the proxy cannot judge gets a
502with fixed text and no longer shows the host’s nameserver to the sandbox. The cause goes to the daemon log. - Images: the cache refuses a cached manifest or config that no longer matches its digest, and
shard image lslists such an image asunreadable.
v0.1.0
Section titled “v0.1.0”5 October 2026. Release.
The first release:
shardfor Linux on x86-64 and for Apple silicon Macs, and a build for Intel Macs, for client use only.shard-initfor Linux, the systemd units for the daemon and forshard serve, and the launchd service for a Mac.- The
useshardsSDKs 0.1.0 for TypeScript and Python, as files on their own GitHub releases. They were on npm and PyPI by v0.1.1.