Skip to content

Review rm behavior #7076

Description

@chapati

Description

In the #2677 a choice was made to return 0 in case container doesn't exist.

Good intention, terrible execution, 0 exit code is returned but error is printed to console

docker rm -f nonexistent
Error response from daemon: No such container: nonexistent

Why this is bad

  • It Breaks Log Parsing: If one writes an automated monitoring agent (like Datadog or a simple log scraper) to watch server logs for the string "Error response from daemon", it will trigger a false-positive alert every time a clean, successful container purge script runs.

  • It Destroys Trust in set -e: Developers use set -e specifically so they don't have to manually write error checking after every single line of code. By making a command print a blatant error but return a success code, Docker actively gaslights the shell environment.

  • It Introduces Deception: it forces developers to write wildly over-engineered safety guards (like parsing docker inspect --type=container) just to protect their scripts from Docker’s internal exit-code lying.

If a tool prints the word "Error", it should emit an error code. If it returns "Success", it should shut up. Docker trying to do both at the same time is bad API design, plain and simple.

Reproduce

docker rm -f nonexistent
echo "DEBUG: 'docker rm' exited with code: $?"

Result:
Error response from daemon: No such container: nonexistent
DEBUG: 'docker rm' exited with code: 0

Expected behavior

On 0 return code no error message should be produced

docker version

Client:
 Version:           29.4.0-ce
 API version:       1.54
 Go version:        go1.26.3
 Git commit:        daa0cb7f23
 Built:             Wed May  6 04:59:34 2026
 OS/Arch:           linux/amd64
 Context:           default

Server:
 Engine:
  Version:          29.4.0-ce
  API version:      1.54 (minimum version 1.40)
  Go version:       go1.26.3
  Git commit:       daa0cb7f23
  Built:            Wed May  6 04:59:34 2026
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.7.29
  GitCommit:        442cb34bda9a6a0fed82a2ca7cade05c5c749582
 runc:
  Version:          1.4.1
  GitCommit:        v1.4.1-0-gc67132530367
 docker-init:
  Version:          0.2.1_catatonit
  GitCommit:

docker info

Client:
 Version:    29.4.0-ce
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  0.33.0
    Path:     /usr/lib/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  5.1.4
    Path:     /usr/lib/docker/cli-plugins/docker-compose

Server:
 Containers: 6
  Running: 5
  Paused: 0
  Stopped: 1
 Images: 30
 Server Version: 29.4.0-ce
 Storage Driver: overlayfs
  driver-type: io.containerd.snapshotter.v1
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 CDI spec directories:
  /etc/cdi
  /var/run/cdi
 Swarm: active
  NodeID: kmynlms2gqysq120xhxbqe6sl
  Is Manager: true
  ClusterID: 01w7otx4wv6p9ycpn9t9b76q0
  Managers: 1
  Nodes: 1
  Default Address Pool: 10.0.0.0/8  
  SubnetSize: 24
  Data Path Port: 4789
  Orchestration:
   Task History Retention Limit: 5
  Raft:
   Snapshot Interval: 10000
   Number of Old Snapshots to Retain: 0
   Heartbeat Tick: 1
   Election Tick: 10
  Dispatcher:
   Heartbeat Period: 5 seconds
  CA Configuration:
   Expiry Duration: 3 months
   Force Rotate: 0
  Autolock Managers: false
  Root Rotation In Progress: false
  Node Address: 192.168.0.111
  Manager Addresses:
   192.168.0.111:2377
 Runtimes: io.containerd.runc.v2 oci runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 442cb34bda9a6a0fed82a2ca7cade05c5c749582
 runc version: v1.4.1-0-gc67132530367
 init version: 
 Security Options:
  apparmor
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version: 7.0.12-1-default
 Operating System: openSUSE Tumbleweed
 OSType: linux
 Architecture: x86_64
 CPUs: 32
 Total Memory: 62.51GiB
 Name: localhost.localdomain
 ID: 5d0600ed-7c12-4f09-84f7-158a0ef492fc
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  ::1/128
  127.0.0.0/8
 Live Restore Enabled: false
 Firewall Backend: iptables+firewalld

Additional Info

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions