Swarm & Harbor: Docker login constantly failing with "http: server gave HTTP response to HTTPS client"

Hello to the community,

I’m reaching because I’ve been trying to troubleshoot this issue for a few days now, and I’m literally getting crazy.

I’m working with a SWARM environment with multiple nodes deployed (1 manager and 3 workers).

On this environment, I’ve got a harbor stack deployed on the manager node (including proxy, core, registry, etc). To deploy harbor, I’ve set the http port to 8080 and deactivated https.
On the docker compose, I’ve exposed 8080:8080 to make the proxy publicly available.

On every machine, I have added /etc/docker/daemon.json with insecure-registries to allow http connection to the harbor_proxy. I indeed restarted docker afterwards and I confirm that the insecure registries are visible from docker info on all machines.

On the manager node, docker login <MANAGER_NODE_IP>:8080 is successful.
On the worker nodes, docker login <MANAGER_NODE_IP>:8080 returns:

time="2025-10-29T12:38:34Z" level=info msg="Error logging in to endpoint, trying next endpoint" endpoint="{https://10.100.4.27:8080 0xc0001f5a40}" error="Get \"https://10.100.4.27:8080/v2/\": http: server gave HTTP response to HTTPS client"
Get "https://10.100.4.27:8080/v2/": http: server gave HTTP response to HTTPS client

A curl -u admin:password <MANAGER_NODE_IP>/v2/_catalog:8080 returns properly the catalog.

I have also tried to deploy the harbor_proxy on global mode, updated the registries etc, it’s all the same, I always get the https error.

I also gave a try to just un-install entirely docker from the VM, remove all config files, etc, nothing works.

I’ve tried plenty of things with IA help, but it’s looping again and again asking me to edit daemon.json, restart docker, and try again.

I’m getting desperate now, I’ve been doing the same steps for a few days, nothing work.

Please give me support!!

Best,
Anthony

Please share the output of:
cat /etc/docker/daemon.json of the manager node where it works, and the worker nodes where it doesn’t.

I suspect that the managed node has the ip configured as insecure registry, while the workers don’t.

If the daemon.json is identical on all hosts, it could very well be a bug in swarm.

In this case you might need to create a ca, create a self-signed certificate for harbor, configure harbor to use it, then configure each node to use the ca certificate.

The last step is docker specific:

  • Create the directory for the registry:
    sudo mkdir -p /etc/docker/certs.d/<MANAGER_NODE_IP>:8080
  • Copy the CA certificate:
    sudo cp your_ca.crt /etc/docker/certs.d/<MANAGER_NODE_IP>:8080/ca.crt
    The file must have a .crt extension and be in PEM format.
  • Restart Docker:
    sudo systemctl restart docker