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
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
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
or:
wget --no-check-certificate https://example.com
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
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"
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"]
}
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
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:
Add the proxy CA certificate to the operating system trust store.
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
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
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
Update the operating system certificate trust database:
sudo update-ca-trust extract
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/
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
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/
Create the proxy configuration file:
sudo vi /etc/systemd/system/docker.service.d/http-proxy.conf
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"
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
Verify that Docker is running:
sudo systemctl status docker
Step 6: Test Docker Login and Image Pull
Test Docker Hub authentication:
docker login
Then test an image pull:
docker pull hello-world
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
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/
Expected output should include:
ca.crt
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
Check Docker Service Logs
Review Docker daemon logs for detailed certificate or proxy errors:
sudo journalctl -u docker -n 100 --no-pager
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
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)