docker/cli · error
failed to retrieve context tls info
Error message
failed to retrieve context tls info: %w
What it means
Returned by docker.Endpoint.tlsConfig() (reached via Endpoint.ClientOpts()) when tls.X509KeyPair(cert, key) fails to build a TLS certificate from the context's stored PEM material. The wrapped error is Go stdlib crypto/tls, indicating malformed PEM, a truncated blob, or a key/cert that do not correspond.
Solutions
- Re-import a matching cert+key pair into the context (docker context import / context update with correct TLS material).
- Verify the pair offline: `openssl x509 -in cert.pem -noout`, `openssl rsa -in key.pem -check`, and compare modulus (`openssl x509 -modulus`, `openssl rsa -modulus`).
- Recreate the context's TLS material from known-good files.
Example fix
// before
opts, err := endpoint.ClientOpts() // -> "failed to retrieve context tls info"
// after: validate the pair before relying on the endpoint
if _, err := tls.X509KeyPair(certPEM, keyPEM); err != nil {
return fmt.Errorf("reload cert/key before use: %w", err)
}
opts, err := endpoint.ClientOpts() Defensive patterns
Strategy: validation
Validate before calling
// Validate the cert/key pair before constructing client opts.
if ep.TLSData != nil && ep.TLSData.Key != nil && ep.TLSData.Cert != nil {
if _, err := tls.X509KeyPair(ep.TLSData.Cert, ep.TLSData.Key); err != nil {
return fmt.Errorf("context TLS material is unusable: %w", err)
}
}
opts, err := ep.ClientOpts() Prevention
- Always update cert and key together when rotating credentials.
- Verify a pair with openssl (modulus match) before importing into a context.
- Keep PEM material in PEM (not DER) and avoid editing it by hand.
When it happens
Trigger: Calling endpoint.ClientOpts() for a context whose TLS material has a cert/key pair failing X509KeyPair: key and cert mismatched, cert not actually a certificate, key not in PEM format, or files truncated/corrupted. Only reached when ep.Host is a non-socket host and ep.TLSData has both Key and Cert set.
Common situations: Cert rotation that updated only cert or only key; pointing a context at the wrong key file; manually editing TLS files and truncating PEM headers; DER instead of PEM; copy-paste leaving stray whitespace.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to retrieve context tls info: ca.pem seems invalid
- no valid private key found
- TLS data for / / does not exist
- default context cannot be edited
- file contents must be in PEM format
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/505b5b2f1d5288a5.
Report an issue: GitHub.
Appendix: source
Thrown at cli/context/docker/load.go:72
return nil, errors.New("failed to retrieve context tls info: ca.pem seems invalid")
}
tlsOpts = append(tlsOpts, func(cfg *tls.Config) {
cfg.RootCAs = certPool
})
}
if ep.TLSData != nil && ep.TLSData.Key != nil && ep.TLSData.Cert != nil {
keyBytes := ep.TLSData.Key
pemBlock, _ := pem.Decode(keyBytes)
if pemBlock == nil {
return nil, errors.New("no valid private key found")
}
if x509.IsEncryptedPEMBlock(pemBlock) { //nolint:staticcheck // SA1019: x509.IsEncryptedPEMBlock is deprecated, and insecure by design
return nil, errors.New("private key is encrypted - support for encrypted private keys has been removed, see https://docs.docker.com/go/deprecated/")
}
x509cert, err := tls.X509KeyPair(ep.TLSData.Cert, keyBytes)
if err != nil {
return nil, fmt.Errorf("failed to retrieve context tls info: %w", err)
}
tlsOpts = append(tlsOpts, func(cfg *tls.Config) {
cfg.Certificates = []tls.Certificate{x509cert}
})
}
if ep.SkipTLSVerify {
tlsOpts = append(tlsOpts, func(cfg *tls.Config) {
cfg.InsecureSkipVerify = true
})
}
return tlsconfig.ClientDefault(tlsOpts...), nil
}
// ClientOpts returns a slice of Client options to configure an API client with this endpoint
func (ep *Endpoint) ClientOpts() ([]client.Opt, error) {
var result []client.Opt
if ep.Host != "" {
helper, err := connhelper.GetConnectionHelper(ep.Host)View on GitHub (pinned to 4f84911bfe)