Skip to content

Containers local dev on WSL2 (kernel 6.18.x): app container never created, only egress proxy-everything sidecar; 'Container failed to start' #231

Description

@ousszizou

Summary

Running a @cloudflare/sandbox container in local dev on WSL2 (kernel 6.18.x) never starts the container. Miniflare/workerd builds the image and starts the egress cloudflare/proxy-everything sidecar, but the actual app container is never created. The readiness probe to the container aborts and workerd throws kj/timer.c++:30: overloaded: operation timed out, surfacing as Container failed to start. Deployed/remote containers are unaffected — this is local-dev only.

Expected vs actual

  • Expected: getSandbox(env.SANDBOX, id).exec("echo hi") starts the container and returns.
  • Actual: the call hangs ~100s; the DO retries; only a workerd-<worker>-<DO>-<id>-proxy container exists in docker ps — the app container (cloudflare-dev/<class>:<hash>) is never created. Fails with Container failed to start.

Dev-server output

{ level: 'info', message: 'Using http transport', component: 'sandbox-do', ... }
Error checking if container is ready: The operation was aborted   (x4)
e = kj/timer.c++:30: overloaded: operation timed out
  <workerd stack>; sentryErrorContext = jsgInternalError; wdErrId = ...
{ level: 'error', message: 'Sandbox error', error: { message: 'Container failed to start' } }
{ level: 'warn',  message: 'container.startup', outcome: 'unrecognized_error', error: 'Container failed to start' }
{ level: 'info',  message: 'Container not ready, retrying', status: 503, attempt: N }

Minimal reproduction

wrangler.jsonc

{
  "name": "sbx-repro",
  "main": "src/index.ts",
  "compatibility_date": "2026-07-01",
  "containers": [{ "class_name": "Sandbox", "image": "./Dockerfile", "instance_type": "basic", "max_instances": 1 }],
  "durable_objects": { "bindings": [{ "name": "SANDBOX", "class_name": "Sandbox" }] },
  "migrations": [{ "tag": "v1", "new_sqlite_classes": ["Sandbox"] }]
}

Dockerfile

FROM docker.io/cloudflare/sandbox:0.12.3

src/index.ts

import { getSandbox } from "@cloudflare/sandbox";
export { Sandbox } from "@cloudflare/sandbox";

export default {
  async fetch(_req: Request, env: { SANDBOX: DurableObjectNamespace }) {
    const sandbox = getSandbox(env.SANDBOX, "repro");
    const result = await sandbox.exec("echo hi");
    return Response.json(result);
  },
};
  1. On WSL2 with a 6.18.x kernel and native docker-ce (containerd image store), run the dev server (@cloudflare/vite-plugin pnpm dev, or wrangler dev).
  2. curl http://127.0.0.1:<port>/.
  3. Request hangs, then Container failed to start. docker ps shows only the ...-proxy sidecar, never the app container.

Key evidence (failure is workerd/miniflare-side, not the image or Docker)

  • The built image runs fine standalone: docker run --rm cloudflare-dev/<class>:<hash> boots and the container-server listens on :3000.
  • Docker daemon logs (journalctl -u docker) during a run show only the -proxy endpoint joining the bridge (recreated in a ~30s loop). There is no create/start for the app-image container — the create never reaches the daemon.
  • Host→container TCP and HTTP on :3000 = 200 in ~2ms; docker0 (172.17.0.1) present and bindable. Networking to a manually-run container is fine.
  • The only thing the app-container create does that a plain docker run and the proxy create do not is wire the container into the egress proxy's network — that step appears to be where it hangs.

What was ruled out

  • Toolchain version — reproduced on both workerd 1.20260521.1 and the newest workerd 1.20260701.1.
  • The image / disk / BuildKit — image builds (docker build rc=0) and runs standalone; isolated builds succeed.
  • enableInternet — a Sandbox extends Base { enableInternet = false } subclass does not help; the proxy-everything sidecar is created for every local container regardless (see workers-sdk#14242).
  • Docker Desktop — not in use; native docker-ce, active context default. A stale desktop-linux context was removed with no change.
  • BuildKit only one connection allowed session warnings — temporally disjoint from the container-start attempts; not related.

Hypothesis

An environment regression in the local-dev container↔egress-proxy networking path (miniflare/workerd) on WSL2 kernel 6.18.x. The container image, Docker, and host↔container networking all work in isolation; only workerd's app-container create (with proxy network wiring) fails. It is not fixed by upgrading the toolchain or by app-level config.

Environment

OS WSL2 (Ubuntu), kernel 6.18.33.2-microsoft-standard-WSL2 (built 2026-06-18), WSL 2.7.10.0
Docker native docker-ce 29.6.1 (not Docker Desktop); containerd image store (overlayfs / io.containerd.snapshotter.v1)
@cloudflare/sandbox 0.12.3 (also 0.10.3)
@cloudflare/containers 0.3.7 (also 0.3.5)
@cloudflare/vite-plugin 1.43.0 (also 1.38.0)
wrangler 4.107.0 (also 4.94.0)
miniflare 4.20260701.0 (also 4.20260521.0)
workerd 1.20260701.1 (also 1.20260521.1)
Node 22.x

Possibly related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions