This error occurs when Docker Swarm cannot locate a secret that a service is trying to use. The fix typically involves creating the missing secret, verifying secret names match between your service definition and the secret store, or ensuring you're operating on a Swarm manager node.
The "secret not found" error in Docker Swarm indicates that the orchestrator cannot locate a secret referenced by your service in the cluster's secret store. Docker Swarm secrets are a secure way to manage sensitive data like passwords, API keys, and certificates that your containers need at runtime. When you deploy a service that references a secret by name, Docker Swarm looks up that secret in its internal encrypted store (managed by the Raft consensus algorithm across manager nodes). If the secret doesn't exist or the name doesn't match exactly, you'll see this error. Unlike environment variables, Swarm secrets are encrypted at rest and in transit, and are only mounted into containers that explicitly need them via an in-memory tmpfs filesystem at `/run/secrets/<secret_name>`. This makes them the recommended way to handle sensitive configuration in production Swarm deployments.
First, check what secrets currently exist in your Swarm cluster:
docker secret lsThis command must be run on a Swarm manager node. If you see your secret listed, the issue is likely a name mismatch. If it's not listed, you need to create it.
You can also inspect a specific secret to see its metadata (not the value):
docker secret inspect mysecretSecret management commands only work on manager nodes. Check your node's role:
docker info | grep "Is Manager"If you see "Is Manager: false" or get an error about Swarm not being active, you need to either:
1. SSH into a manager node, or
2. Initialize Swarm if it's not running:
docker swarm initCreate the secret using one of these methods:
From a file:
docker secret create mysecret /path/to/secret/fileFrom stdin (recommended for sensitive data):
echo "my_secret_value" | docker secret create mysecret -Or using printf to avoid newline issues:
printf "my_secret_value" | docker secret create mysecret -After creation, verify it exists:
docker secret lsCheck your docker-compose.yml or service definition to ensure the secret name matches exactly (case-sensitive).
In docker-compose.yml:
services:
myapp:
image: myapp:latest
secrets:
- mysecret # Must match the secret name exactly
secrets:
mysecret:
external: true # References an existing Swarm secretFor external secrets, the name must match what's in docker secret ls. If you're defining the secret in the compose file itself:
secrets:
mysecret:
file: ./my_secret.txt # Creates secret from file during deployAfter creating or fixing the secret, redeploy your service:
Using docker stack:
docker stack deploy -c docker-compose.yml mystackUsing docker service:
docker service update --secret-add mysecret myserviceOr if recreating the service:
docker service create --name myservice --secret mysecret myimageOnce the service is running, verify the secret is mounted correctly:
docker exec -it <container_id> ls -la /run/secrets/
docker exec -it <container_id> cat /run/secrets/mysecretThe secret should be available as a file at /run/secrets/mysecret. Your application should read from this file path, not from an environment variable.
Secret name vs ID: When using docker service update --secret-add, you must use the secret name, not its ID. Using the ID will result in a "secret not found" error even if the secret exists. This is a common gotcha.
Secrets are immutable: You cannot update an existing secret's value. To change a secret, you must:
1. Create a new secret with a different name
2. Update the service to use the new secret
3. Remove the old secret
docker secret create mysecret_v2 /path/to/new/secret
docker service update --secret-rm mysecret --secret-add mysecret_v2 myservice
docker secret rm mysecretUsing secrets with docker-compose (without Swarm): In non-Swarm mode, docker-compose can still use secrets, but they work differently. The secret file is bind-mounted directly:
secrets:
mysecret:
file: ./secrets/mysecret.txt # Local file path_FILE environment variables: Many official Docker images support the _FILE suffix pattern. Instead of:
environment:
- MYSQL_PASSWORD=/run/secrets/db_password # WRONG - this is a stringUse:
environment:
- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_password # CORRECTSecret rotation in production: For zero-downtime secret rotation:
1. Create the new secret
2. Update the service with both old and new secrets
3. Update application to use new secret
4. Remove old secret from service
5. Delete old secret from Swarm
Debugging secret issues:
# Check service logs
docker service logs myservice
# Inspect service to see attached secrets
docker service inspect myservice --pretty | grep -A 10 Secrets
# Check if container is receiving the secret
docker inspect <container_id> | jq '.[0].Mounts[] | select(.Type=="tmpfs")'image operating system "linux" cannot be used on this platform
How to fix 'image operating system linux cannot be used on this platform' in Docker
manifest unknown: manifest unknown
How to fix 'manifest unknown' in Docker
cannot open '/etc/passwd': Permission denied
How to fix 'cannot open: Permission denied' in Docker
Error response from daemon: failed to create the ipvlan port
How to fix 'failed to create the ipvlan port' in Docker
toomanyrequests: Rate exceeded for anonymous users
How to fix 'Rate exceeded for anonymous users' in Docker Hub