“curl error 28” means Composer timed out while making a network request. Test from inside the PHP container, because successful browsing on the Docker host does not prove that the container has working DNS, routing, proxy, and certificate settings.
Last updated: October 20, 2026.
docker compose exec app composer diagnose -vvv
docker compose exec app php -r "echo gethostbyname('repo.packagist.org'), PHP_EOL;"
docker compose exec app php -r "var_dump(file_get_contents('https://repo.packagist.org/packages.json') !== false);"Replace app with the PHP service name from your Compose file. Run the checks during a failure, not only after a retry succeeds, and preserve the verbose output without publishing tokens or proxy credentials.
Separate DNS, HTTPS, and Composer problems
If gethostbyname() prints the hostname unchanged, name resolution failed inside the container. Inspect the container network and Docker daemon DNS configuration. Docker’s networking documentation explains that containers have their own interfaces, routes, gateways, and DNS view even when outbound access normally follows the host.
If DNS returns an IP but the HTTPS request times out, check VPN, firewall, proxy, and outbound port 443 rules. If it fails with a certificate error instead, update the image’s CA certificates and confirm which CA bundle PHP uses. Do not disable TLS verification.
Use Composer diagnostics before changing timeouts
Composer’s official network-timeout guidance recommends composer diagnose and describes curl error 28 as a network request exceeding its timeout. Increasing default_socket_timeout may help a genuinely slow connection, but it does not repair intermittent DNS or a blocked route.
A broken IPv6 route can also delay requests. Composer documents COMPOSER_IPRESOLVE=4 as a diagnostic workaround when the curl extension handles downloads. Use it to confirm an IPv6 problem, then correct the host or network configuration rather than keeping an unexplained workaround.
After the repair, rebuild or restart the affected container and rerun the same three checks several times. A single successful retry is not enough evidence when the original failure was intermittent. Keep Composer’s cache enabled unless diagnostics show corruption; cached metadata may explain why a later command succeeds while browser access still fails.
Continue with installing and configuring PHP, fixing local PHP asset paths, and diagnosing PHP cURL failures.