docker/cli · error
failed to list TLS files for endpoint
Error message
failed to list TLS files for endpoint %s: %w
What it means
Emitted by tlsStore.listContextData when iterating over a context's endpoint subdirectories and os.ReadDir on an individual endpoint dir fails with an error other than os.IsNotExist. It wraps the underlying syscall/IO error so callers know which endpoint directory under ~/.docker/contexts/<context>/tls could not be enumerated. The error propagates up through ListTLSFiles and LoadTLSData, aborting TLS-material loading for that context.
Solutions
- Run `ls -la ~/.docker/contexts/meta/*/tls/<endpoint>/` (the path printed via the endpoint name) and chmod/chown it so the current user can read it.
- If the context is corrupted, recreate it: `docker context rm <name>` then `docker context create <name> ...` with the correct TLS flags.
- Remove dangling symlinks or restore the missing files, then re-run the failing command.
- On SELinux systems run `restorecon -Rv ~/.docker` to fix labels.
Example fix
// before: relying on a broken context store path
ctx, err := store.ListTLSFiles("myctx")
// after: validate the TLS dir is readable before delegating to the store
if fi, err := os.Stat(filepath.Join(tlsRoot, contextdir)); err != nil {
return fmt.Errorf("TLS dir unreadable for %s: %w", contextdir, err)
} else if fi.Mode().Perm()&0o400 == 0 {
return fmt.Errorf("no read permission on TLS dir %s", contextdir)
} Defensive patterns
Strategy: validation
Validate before calling
// Verify each endpoint TLS dir is readable before calling ListTLSFiles
dir := filepath.Join(tlsRoot, contextdirOf(name))
entries, err := os.ReadDir(dir)
if err != nil {
return fmt.Errorf("pre-check TLS dir %s: %w", dir, err)
}
for _, e := range entries {
if !e.IsDir() { continue }
ep := filepath.Join(dir, e.Name())
if fi, err := os.Stat(ep); err != nil {
return fmt.Errorf("endpoint TLS dir %s unreadable: %w", ep, err)
} else if fi.Mode().Perm()&0o400 == 0 {
return fmt.Errorf("no read permission on %s", ep)
}
} Prevention
- Keep ~/.docker ownership consistent with the user running docker (avoid sudo churn).
- Never hand-edit the contexts/meta TLS tree; use docker context create/update.
- Avoid running concurrent context mutations against the same context.
When it happens
Trigger: Calling s.ListTLSFiles(name) where the context's TLS base directory exists and one endpoint subdirectory (e.g. ~/.docker/contexts/meta/<hash>/tls/<endpoint>/) is unreadable due to a permissions error, a broken symlink, an I/O error, or a race where the dir is removed mid-read. The inner os.ReadDir at tlsstore.go:75 returns a non-nil, non-NotExist error.
Common situations: Filesystem permission drift after running docker as root then non-root (or sudo chown of ~/.docker), a manually edited/corrupted context store, a stale symlink left by a moved home directory, SELinux/AppArmor denying reads, or a concurrent docker context rm that deletes the dir between the outer and inner ReadDir.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- failed to read TLS data for endpoint
- failed to list TLS files for context
- failed to retrieve TLS files for context
- failed to retrieve TLS data
- error reading from
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/5768885019ce4af6.
Report an issue: GitHub.
Appendix: source
Thrown at cli/context/store/tlsstore.go:80
func (s *tlsStore) listContextData(name string) (map[string]EndpointFiles, error) {
contextDir := s.contextDir(name)
epFSs, err := os.ReadDir(contextDir)
if err != nil {
if os.IsNotExist(err) {
return map[string]EndpointFiles{}, nil
}
return nil, fmt.Errorf("failed to list TLS files for context %s: %w", name, err)
}
r := make(map[string]EndpointFiles)
for _, epFS := range epFSs {
if epFS.IsDir() {
fss, err := os.ReadDir(filepath.Join(contextDir, epFS.Name()))
if os.IsNotExist(err) {
continue
}
if err != nil {
return nil, fmt.Errorf("failed to list TLS files for endpoint %s: %w", epFS.Name(), err)
}
var files EndpointFiles
for _, fs := range fss {
if !fs.IsDir() {
files = append(files, fs.Name())
}
}
r[epFS.Name()] = files
}
}
return r, nil
}
// EndpointFiles is a slice of strings representing file names
type EndpointFiles []string
View on GitHub (pinned to 4f84911bfe)