nextcloud/all-in-one · critical · \Exception

Could not start container {identifier}: {details}

Error message

Could not start container {identifier}: {details}

What it means

The Docker daemon answered POST /containers/{id}/start with an error (Guzzle RequestException carries the response) and the daemon's JSON error body is embedded as {details}. Note details can render empty when the failure occurred before any HTTP response existed. The start request performs port allocations, so daemon-level resource conflicts surface here.

Source

Thrown at php/src/Docker/DockerActionManager.php:202

            $response = substr($line, 8) . $separator;
        }

        while (($line = strtok($separator)) !== false) {
            $response .= substr($line, 8) . $separator;
        }

        return $response;
    }

    public function StartContainer(Container $container, ?\Closure $addToStreamingResponseBody = null): void {
        $url = $this->BuildApiUrl(sprintf('containers/%s/start', urlencode($container->identifier)));
        try {
            if ($addToStreamingResponseBody !== null) {
                $addToStreamingResponseBody("Starting container", $container);
            }
            $this->sendHttpRequest('POST', $url);
        } catch (RequestException $e) {
            throw new \Exception("Could not start container " . $container->identifier . ": " . $e->getResponse()?->getBody()->getContents());
        }
    }

    public function CreateVolumes(Container $container): void {
        $url = $this->BuildApiUrl('volumes/create');
        foreach ($container->volumes->GetVolumes() as $volume) {
            $forbiddenChars = [
                '/',
            ];

            if ($volume->name === 'nextcloud_aio_nextcloud_datadir' || $volume->name === 'nextcloud_aio_backupdir') {
                continue;
            }

            $firstChar = substr($volume->name, 0, 1);
            if (!in_array($firstChar, $forbiddenChars)) {
                $this->sendHttpRequest(
                    'POST',

View on GitHub (pinned to 6b788eec5e)

Solutions

  1. Run docker logs and docker inspect on the failing container for the daemon's detailed reason
  2. If the error is 'already started', treat it as success or stop the container first
  3. Free conflicting host ports: ss -ltnp to find holders, stop the overlapping service/container
  4. Check host disk space and mount targets, then retry the start

Example fix

// before: any RequestException is fatal
try { $docker->StartContainer($c); } catch (\Exception $e) { throw $e; }
// after: treat 'already started' (409) as success
use GuzzleHttp\Exception\RequestException;
try {
    $docker->StartContainer($c);
} catch (\Exception $e) {
    if (str_contains($e->getMessage(), 'already started')) { return; }
    throw $e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Skip the start call entirely when the container is already running
$state = $docker->sendHttpRequest('GET', $docker->BuildApiUrl('containers/' . rawurlencode($id) . '/json'));
$info = json_decode($state->getBody()->getContents(), true);
if (($info['State']['Running'] ?? false) === true) {
    return; // already started — POST would 409
}

Try / catch

try {
    $docker->StartContainer($container);
} catch (\Exception $e) {
    $msg = $e->getMessage();
    if (str_contains($msg, 'already started')) { return; } // idempotent success
    if (str_contains($msg, 'port is already allocated')) { freePortsOrReport($msg); return; }
    throw $e;
}

Prevention

When it happens

Trigger: Container already running (409 'container already started'); host port allocation conflict with another process/container; storage or mount driver errors; SELinux/AppArmor denial; architecture-mismatched image failing to start.

Common situations: Re-running start on an already-running AIO container; another service binding the same host ports; full disk or missing mount targets; leftover containers from a failed update holding resources.

Related errors


AI-assisted analysis of nextcloud/all-in-one@6b788eec5e (2026-08-21). Data as JSON: /api/errors/5856a684377185fa. Report an issue: GitHub.