nextcloud/all-in-one · critical · \Exception
Could not pull image {imageName} (attempt {attempt}/{maxRetr
Error message
Could not pull image {imageName} (attempt {attempt}/{maxRetries}): {errorDetails} What it means
The pull loop (maxRetries = 3, 1s sleep between attempts, streaming POST images/create with per-line error events) exhausted all attempts and the image was confirmed absent locally beforehand (GET images/{name}/json failed), so the last error is thrown with attempt count and details. If the image WAS already present locally, the failure is only logged via error_log and the method continues — the exception means there is no local fallback.
Source
Thrown at php/src/Docker/DockerActionManager.php:616
$interval = time() - $lastHeartbeat;
if ($interval >= self::PULL_HEARTBEAT_INTERVAL_SECONDS) {
$addToStreamingResponseBody(".", $container);
$lastHeartbeat = $now;
}
}
}
if ($pullErrors !== []) {
throw new \Exception(implode('; ', $pullErrors));
}
break;
} catch (\Exception $e) {
$errorDetails = $e instanceof RequestException
? $e->getResponse()?->getBody()->getContents()
: $e->getMessage();
$message = "Could not pull image " . $imageName . " (attempt $attempt/$maxRetries): " . $errorDetails;
if ($attempt === $maxRetries) {
if ($imageIsThere === false) {
throw new \Exception($message);
} else {
error_log($message);
}
} else {
error_log($message . ' Retrying...');
sleep(1);
}
}
}
}
private function isContainerUpdateAvailable(string $id): string {
$container = $this->containerDefinitionFetcher->GetContainerById($id);
$updateAvailable = "";
if ($container->GetUpdateState() === VersionState::Different) {
$updateAvailable = '1';
}View on GitHub (pinned to 6b788eec5e)
Solutions
- Pull manually on the host: docker pull <imageName> to see the daemon's full error
- On 429 toomanyrequests: wait the quota window or docker login (authenticated limits are higher), or configure a registry mirror
- Verify the tag actually exists in the registry before deploying
- Check DNS/egress from the docker host to the registry and retry once fixed
Example fix
// before: hard fail after 3 attempts
// after: caller-level backoff with jitter before giving up
$attempts = [5, 30, 120];
foreach ($attempts as $i => $delay) {
try {
$docker->PullImage($container, $stream);
break;
} catch (\Exception $e) {
if ($i === count($attempts) - 1) { throw $e; }
error_log('Pull failed, retrying in ' . $delay . 's: ' . $e->getMessage());
sleep($delay);
}
} Defensive patterns
Strategy: retry
Validate before calling
// Pre-check local presence so an absent image + failing registry fails fast and clearly
try {
$docker->sendHttpRequest('GET', $docker->BuildApiUrl('images/' . rawurlencode($imageName) . '/json'));
$present = true;
} catch (\Throwable) {
$present = false; // pull is mandatory — ensure egress/quota before continuing
} Try / catch
// Library already retries 3x internally; caller should retry with LONGER backoff
// (rate-limit windows are minutes, so immediate retries cannot help)
try {
$docker->PullImage($container, $stream);
} catch (\Exception $e) {
if (str_contains($e->getMessage(), 'toomanyrequests')) {
scheduleRetry(15 * 60); // Docker Hub quota window
return;
}
throw $e;
} Prevention
- docker login on the host raises Docker Hub pull limits — do it before running AIO updates
- Configure a registry mirror or pull-through cache on rate-limited hosts
- Remember the local-image fallback: if the image exists locally, pull failure is logged, not thrown — pre-pulling key images buys resilience
When it happens
Trigger: Tag or repository does not exist ('manifest unknown'); Docker Hub anonymous pull rate limit (429 toomanyrequests); no route/DNS to the registry; private image without credentials; a transient network error repeating three times; every pull-stream event carried an 'error' key.
Common situations: Docker Hub rate limits on busy or shared-IP hosts; typo'd or not-yet-published AIO channel tag; air-gapped host without a registry mirror; restricted egress blocking registry-1.docker.io.
Related errors
- ${DataConst::GetDataDirectory()} does not exist! Something w
- ${DataConst::GetDataDirectory()} does not have enough space
- Could not register a free dedyn.io domain after {maxSlugAtte
- Could not start container {identifier}: {details}
- Could not create container {identifier}: {details}
AI-assisted analysis of nextcloud/all-in-one@6b788eec5e (2026-08-21).
Data as JSON: /api/errors/9fa38fb94e1e0294.
Report an issue: GitHub.