docker/cli · error
failed to remove metadata
Error message
failed to remove metadata: %w
What it means
Returned by metadataStore.remove (reached via ContextStore.Remove -> 510) when os.RemoveAll of the context's metadata directory fails. The wrapped error is the OS error, typically a permission denial or I/O error.
Solutions
- Fix ownership/permissions on the context dir under ~/.docker/contexts/meta/<hash> (e.g. `sudo chown -R $USER ~/.docker/contexts`).
- Remove the directory manually as the appropriate user: `rm -rf ~/.docker/contexts/meta/<hash>`.
- Confirm the filesystem is writable and not mounted read-only.
Defensive patterns
Strategy: try-catch
Try / catch
if err := store.Remove(name); err != nil {
var perr *os.PathError
if errors.As(err, &perr) && errors.Is(perr.Err, os.ErrPermission) {
// fix ownership/permissions, then retry or remove the dir manually
}
return err
} Prevention
- Run context-management commands as the user that owns ~/.docker.
- Avoid creating context files as root for a non-root user.
- After root-created contexts, chown ~/.docker/contexts back to the user.
When it happens
Trigger: Calling store.Remove(name) / `docker context rm` when the metadata dir or a file within it cannot be deleted: permission denied, read-only filesystem, or a file held open.
Common situations: Files created as root but CLI running as a normal user (or vice versa); read-only mount; another process locking files (Windows AV/indexer); NFS permission quirks.
Related errors
- failed to remove context
- failed to remove the CID file
- failed to read TLS data for endpoint
- failed to remove TLS data
- failed to remove TLS data for endpoint
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/edbccb60ceacd0d3.
Report an issue: GitHub.
Appendix: source
Thrown at cli/context/store/metadatastore.go:101
}
if err := json.Unmarshal(bytes, &untyped); err != nil {
return Metadata{}, fmt.Errorf("parsing %s: %v", fileName, err)
}
r.Name = untyped.Name
if r.Metadata, err = parseTypedOrMap(untyped.Metadata, s.config.contextType); err != nil {
return Metadata{}, fmt.Errorf("parsing %s: %v", fileName, err)
}
for k, v := range untyped.Endpoints {
if r.Endpoints[k], err = parseTypedOrMap(v, s.config.endpointTypes[k]); err != nil {
return Metadata{}, fmt.Errorf("parsing %s: %v", fileName, err)
}
}
return r, err
}
func (s *metadataStore) remove(name string) error {
if err := os.RemoveAll(s.contextDir(contextdirOf(name))); err != nil {
return fmt.Errorf("failed to remove metadata: %w", err)
}
return nil
}
func (s *metadataStore) list() ([]Metadata, error) {
ctxDirs, err := listRecursivelyMetadataDirs(s.root)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return nil, nil
}
return nil, err
}
res := make([]Metadata, 0, len(ctxDirs))
for _, dir := range ctxDirs {
c, err := s.getByID(contextdir(dir))
if err != nil {
if errors.Is(err, os.ErrNotExist) {
continueView on GitHub (pinned to 4f84911bfe)