Safely Remove Docker Swarm Secrets with docker secret rm

docker secret rm is one short command with no undo, no confirmation prompt, and a value Docker cannot hand back once it is gone. This covers a controlled way to remove one or more named Swarm secrets, confirm the names are right first, and verify the objects are actually gone from the manager's inventory afterwards.

Allow about ten minutes for one secret, longer if you need to check services first. You need Docker CLI 29.8.1 or a compatible release, access to a reachable Swarm manager, and the exact secret names or IDs. The local manpage describes docker secret rm SECRET [SECRET...] and no command options at all.

1. Check the installed command

Start with read-only checks. They change nothing and normally need no elevated privileges:

$ docker version --format '{{.Client.Version}}'
29.8.1
$ docker secret rm --help
Usage:  docker secret rm SECRET [SECRET...]

Remove one or more secrets

Your version and help text may differ, but the boundary holds: one or more positional secret references, no force flag, no interactive confirmation flag, no dry run. Do not borrow options from docker container rm or any other Docker resource command.

Checkpoint: if docker secret rm --help shows a different shape on your system, follow that installed help. Do not assume a newer or unrelated command's option applies here.

2. List the exact secrets first

List Swarm secrets and record the exact name or ID you intend to remove:

$ docker secret ls
ID                          NAME              DRIVER    CREATED         UPDATED
abc123...                   old-api-token               3 months ago     3 months ago

An ID is stable for the object; a name is easier for a human to review. Copy it rather than type from memory. Docker secret listings never reveal contents, which is deliberate: if you need to know what a secret contains, go to the controlled source where it was originally recorded, not Docker's output.

Before deleting, check which services refer to the secret:

$ docker service inspect SERVICE_NAME --format '{{json .Spec.TaskTemplate.ContainerSpec.Secrets}}'

Replace SERVICE_NAME with an actual name. An empty result only means this one inspection found nothing attached; check every relevant service, stack definition, deployment repository and runbook. Removing a secret a running service expects can stop tasks starting, or leave a replacement deployment without a credential it needs.

3. Warn the owner and choose the recovery path

Deletion is irreversible from Docker's point of view: there is no docker secret undo, and docker secret inspect cannot restore a value. If the secret is still needed, stop here and create a replacement from the authoritative source before touching service references. Keep the old secret until the replacement is tested, unless your incident procedure demands immediate revocation.

Confirm all of these before running the removal command:

Warning: do not print the secret value into a terminal, shell history, ticket or article while doing this check. Removing a secret is security-sensitive even once it is no longer operationally required.

4. Remove one secret

Run the destructive command only after the checkpoint above. A normal user can run it with ordinary Docker access; use sudo only when your installation deliberately requires it and you have confirmed that privileged context is the correct Swarm manager:

$ docker secret rm old-api-token
old-api-token

On success, Docker prints the removed reference and exits cleanly. That is not the secret value. There is no confirmation prompt, so a typo naming another existing secret removes the wrong object without complaint.

Checkpoint: verify the exit status immediately if this is part of a script or change record:

$ printf 'exit status: %s\n' "$?"
exit status: 0

Treat any failure as unresolved. Do not assume a partial multi-secret command removed every requested object.

5. Remove several named secrets

Pass each already-reviewed name or ID as a separate argument:

$ docker secret rm retired-token old-registry-password
retired-token
old-registry-password

Review the whole command before you press enter. Never build this argument list from an unreviewed docker secret ls pipeline or a wildcard: the manpage accepts explicit references, not a selector. If one reference is wrong or inaccessible, check the output and re-list the remaining secrets rather than blindly repeating the whole command.

Do not include a secret still attached to a service just because its name looks old. Update and test the service with a replacement first, then remove the unused object as a separate change, so service disruption and credential revocation stay visible.

6. Verify the deletion

List secrets again and check the removed name is gone:

$ docker secret ls
ID                          NAME              DRIVER    CREATED         UPDATED
def456...                   current-api-token           2 days ago       2 days ago

Use a format that makes a scripted check unambiguous:

$ docker secret ls --format '{{.ID}}\t{{.Name}}'
def456...	current-api-token

If the old name is still there, check you are connected to the intended context and manager before you inspect the command error. Docker secrets are Swarm objects, not local environment variables or Compose file entries; a successful command against the wrong context is still a failed change.

Common failure modes

Done means