DEV Community

Cover image for How to Fix Docker Login x509 Certificate Errors Behind a Corporate Proxy
Sandesh Pawar
Sandesh Pawar

Posted on

How to Fix Docker Login x509 Certificate Errors Behind a Corporate Proxy

Introduction

Enterprise and banking environments commonly enforce strict network-security controls. Internet access is often limited to a DMZ, while management zones and internal application environments have no direct internet connectivity.

In these environments, outbound traffic usually passes through an approved corporate proxy. This approach improves monitoring, access control, compliance, and auditability. However, it can create an unexpected issue when engineers run Docker commands such as docker login or docker pull.

A common error is:

Error response from daemon: Get "https://registry-1.docker.io/v2/":
tls: failed to verify certificate: x509: certificate signed by unknown authority
Enter fullscreen mode Exit fullscreen mode

This article explains why the error occurs, why common TLS-bypass approaches are not appropriate for Docker, and how to permanently fix the issue by adding the corporate proxy certificate authority (CA) certificate to both the operating system and Docker’s registry trust store.

Why Docker Login Fails in Restricted Banking Environments

In a typical banking infrastructure, environments are segmented to reduce risk:

  • DMZ: Controlled internet access is available through an enterprise proxy.

  • Management Zone (MZ): Administrative systems are isolated from the public internet.

  • Application and production zones: Outbound connectivity is heavily restricted or completely blocked.

  • Corporate proxy: Inspects, controls, logs, and routes approved outbound traffic.

When Docker attempts to connect to Docker Hub, it communicates with endpoints such as:

registry-1.docker.io
docker.io
auth.docker.io
Enter fullscreen mode Exit fullscreen mode

If the corporate proxy performs TLS or SSL inspection, it decrypts and re-encrypts HTTPS traffic. The proxy presents a certificate signed by the organization’s internal CA rather than the public CA expected by Docker.

If Docker does not trust that internal CA, certificate validation fails and Docker returns the x509: certificate signed by unknown authority error.

Why curl -k and wget --no-check-certificate Are Not a Docker Solution

For basic package downloads, teams may temporarily bypass certificate validation with commands such as:

curl -k https://example.com
Enter fullscreen mode Exit fullscreen mode

or:

wget --no-check-certificate https://example.com
Enter fullscreen mode Exit fullscreen mode

These commands disable TLS certificate validation. While they may help with short-term troubleshooting, they should not be used as a permanent solution in a regulated environment.

Docker works differently. Docker image operations are performed by the Docker daemon, which validates registry certificates independently. A successful curl -k test does not mean Docker will trust the same endpoint.

Disabling TLS validation weakens the security model and creates a risk of man-in-the-middle attacks. The correct approach is to install and trust the corporate proxy CA certificate.

Understanding Docker Daemon, Docker CLI, and Proxy Configuration

A frequent source of confusion is the difference between the Docker CLI and the Docker daemon.

Docker CLI

The Docker CLI is the command-line tool used by administrators and developers:

docker login
docker pull nginx
docker build .
docker push my-registry.example.com/app:1.0
Enter fullscreen mode Exit fullscreen mode

The CLI sends commands to the Docker daemon.

Docker Daemon

The Docker daemon is the background service responsible for actions such as:

  • Pulling container images

  • Pushing images to registries

  • Building images

  • Creating and running containers

  • Connecting to external registries

Because the daemon establishes registry connections, proxy configuration and certificate trust must be correctly configured for the daemon.

Proxy Configuration Is Not Certificate Trust

Configuring a proxy tells Docker where to send outbound traffic. It does not automatically make Docker trust certificates generated by a TLS-inspecting proxy.

For example, this configuration routes Docker daemon traffic through a proxy:

[Service]
Environment="HTTP_PROXY=http://example.com"
Environment="HTTPS_PROXY=http://example.com"
Environment="NO_PROXY=localhost,127.0.0.1,.somecompany.com"
Enter fullscreen mode Exit fullscreen mode

However, if the proxy re-signs HTTPS traffic using an internal CA, Docker still requires that CA certificate to validate the connection.

When to Use insecure-registries

Docker supports an insecure-registries setting in /etc/docker/daemon.json.

Example:

{
  "insecure-registries": ["my-registry-ip:5000"]
}
Enter fullscreen mode Exit fullscreen mode

This setting is useful only for an internal registry that is intentionally running over HTTP or has an untrusted certificate.

It should not be used for Docker Hub endpoints such as:

docker.io
registry-1.docker.io
Enter fullscreen mode Exit fullscreen mode

Marking a public registry as insecure disables important security protections. In banking and enterprise environments, the preferred solution is to trust the organization’s proxy CA certificate.

Permanent Fix: Add the Corporate Proxy CA Certificate

The permanent fix has two parts:

  1. Add the proxy CA certificate to the operating system trust store.

  2. Add the proxy CA certificate to Docker’s registry-specific certificate directory.

This ensures that both the host operating system and Docker trust the certificate presented by the corporate proxy.

Step 1: Export the Proxy Certificate

Use OpenSSL to retrieve the certificate chain from Docker Hub through the corporate proxy.

Replace the proxy IP address and port with your environment’s proxy details.

openssl s_client \
  -proxy <Proxy-server-IP>:<Proxy-port> \
  -showcerts \
  -connect registry-1.docker.io:443 \
  </dev/null 2>/dev/null \
  | sed -n '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' \
  > proxy-ca.crt
Enter fullscreen mode Exit fullscreen mode

This command connects to registry-1.docker.io through the proxy and saves the presented certificates into a file named proxy-ca.crt.

Important Validation Step

Before trusting the certificate, confirm that it belongs to the approved corporate proxy or corporate certificate authority.

openssl x509 -in proxy-ca.crt -noout -subject -issuer -dates
Enter fullscreen mode Exit fullscreen mode

Review the certificate subject, issuer, and expiration dates. Do not install an unknown or unapproved certificate.

Step 2: Add the Certificate to the RHEL Trust Store

For RHEL, Rocky Linux, AlmaLinux, CentOS Stream, and similar distributions, copy the CA certificate into the system trust anchor directory.

sudo cp proxy-ca.crt /etc/pki/ca-trust/source/anchors/corporate-proxy.crt
Enter fullscreen mode Exit fullscreen mode

Update the operating system certificate trust database:

sudo update-ca-trust extract
Enter fullscreen mode Exit fullscreen mode

This step allows system tools and services to trust the corporate proxy CA.

Step 3: Add the Certificate to Docker’s Registry Trust Store

Docker supports registry-specific CA certificates under /etc/docker/certs.d/.

Create a directory for the Docker Hub registry endpoint:

sudo mkdir -p /etc/docker/certs.d/registry-1.docker.io/
Enter fullscreen mode Exit fullscreen mode

Copy the corporate proxy CA certificate into the directory using the required filename:

sudo cp proxy-ca.crt /etc/docker/certs.d/registry-1.docker.io/ca.crt
Enter fullscreen mode Exit fullscreen mode

Docker treats *.crt files in this directory as trusted CA roots for that registry.

Step 4: Configure Docker Daemon Proxy Settings

If the Docker host needs the proxy to reach Docker Hub, create a systemd drop-in configuration.

sudo mkdir -p /etc/systemd/system/docker.service.d/
Enter fullscreen mode Exit fullscreen mode

Create the proxy configuration file:

sudo vi /etc/systemd/system/docker.service.d/http-proxy.conf
Enter fullscreen mode Exit fullscreen mode

Add the following configuration and replace the example values:

[Service]
Environment="HTTP_PROXY=http://proxy.example.com:8080"
Environment="HTTPS_PROXY=http://proxy.example.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1,.somecompany.com"
Enter fullscreen mode Exit fullscreen mode

The NO_PROXY value should include internal domains, internal registries, loopback addresses, and services that should not use the corporate proxy.

Step 5: Reload systemd and Restart Docker

After updating the certificate and proxy configuration, reload systemd and restart the Docker daemon.

sudo systemctl daemon-reload
sudo systemctl restart docker
Enter fullscreen mode Exit fullscreen mode

Verify that Docker is running:

sudo systemctl status docker
Enter fullscreen mode Exit fullscreen mode

Step 6: Test Docker Login and Image Pull

Test Docker Hub authentication:

docker login
Enter fullscreen mode Exit fullscreen mode

Then test an image pull:

docker pull hello-world
Enter fullscreen mode Exit fullscreen mode

If the certificate trust and proxy configuration are correct, Docker should connect successfully without the x509 certificate error.

Troubleshooting Checklist

Verify the Docker Daemon Proxy Environment

Run:

sudo systemctl show docker --property=Environment
Enter fullscreen mode Exit fullscreen mode

Confirm that HTTP_PROXY, HTTPS_PROXY, and NO_PROXY are present and correct.

Verify the Docker Certificate File

Confirm that the registry certificate directory exists:

sudo ls -l /etc/docker/certs.d/registry-1.docker.io/
Enter fullscreen mode Exit fullscreen mode

Expected output should include:

ca.crt
Enter fullscreen mode Exit fullscreen mode

Verify the Certificate Format

Docker expects a PEM-formatted certificate. Validate the file:

openssl x509 -in /etc/docker/certs.d/registry-1.docker.io/ca.crt -text -noout
Enter fullscreen mode Exit fullscreen mode

Check Docker Service Logs

Review Docker daemon logs for detailed certificate or proxy errors:

sudo journalctl -u docker -n 100 --no-pager
Enter fullscreen mode Exit fullscreen mode

Confirm Required Docker Hub Endpoints Are Allowed

Depending on the operation, Docker may need access to multiple endpoints, including:

registry-1.docker.io
auth.docker.io
production.cloudflare.docker.com
Enter fullscreen mode Exit fullscreen mode

Your network and proxy teams should allow the required Docker Hub domains according to organizational security policy.

Security Best Practices for Banking and Enterprise Environments

  • Use the approved corporate proxy instead of direct internet access.

  • Do not permanently disable TLS certificate validation.

  • Do not configure public registries as insecure.

  • Obtain the proxy root CA certificate from the security or network team whenever possible.

  • Validate certificate ownership, issuer, expiration date, and fingerprint before installation.

  • Use an internal container registry or approved registry mirror for production workloads.

  • Restrict image sources to approved registries.

  • Scan container images before promoting them to production.

  • Use immutable image tags or image digests for deployment.

  • Document proxy, certificate, and registry configurations as infrastructure-as-code where possible.

Conclusion

The Docker error x509: certificate signed by unknown authority is common in restricted enterprise environments where a corporate proxy performs TLS inspection.

The issue is not solved by configuring only a Docker proxy or by using insecure registry settings for Docker Hub. Proxy configuration controls network routing, while CA certificate installation establishes trust.

The secure and permanent solution is to install the corporate proxy CA certificate into the host operating system trust store and Docker’s registry-specific certificate directory. Once Docker trusts the proxy CA, docker login, docker pull, and image builds can work reliably while maintaining the security controls required in banking environments.

Top comments (0)