docker/cli · error
private key file must not be readable or writable by others
Error message
private key file %s must not be readable or writable by others
What it means
In getPrivKeyBytesFromPath (key_load.go:74-81), on non-Windows the file's mode bits ANDed with nonOwnerReadWriteMask (0o077) are non-zero, meaning group or others have read and/or write permission on the private key file. The loader refuses to use an over-exposed private key as a security guard. This check is skipped on Windows (runtime.GOOS == 'windows').
Solutions
- Tighten permissions to owner-only: chmod 600 <keyfile>, then re-run 'docker trust key load <keyfile>'.
- If a stricter mode is desired, chmod 400; ensure no group/other bits remain (chmod go-rwx).
- Fix the source so future copies preserve 0600 (e.g. cp --preserve=mode, or set umask 077 before creating).
Example fix
# before: key is group/other readable chmod 664 priv.key # or it was extracted loose docker trust key load priv.key # -> must not be readable by others # after chmod 600 priv.key docker trust key load priv.key
Defensive patterns
Strategy: validation
Validate before calling
// Enforce owner-only permissions before handing the path to the loader.
func enforceKeyFilePerms(path string) error {
if runtime.GOOS == "windows" {
return nil // check skipped on Windows by the loader
}
info, err := os.Stat(path)
if err != nil {
return err
}
if info.Mode()&0o077 != 0 {
if err := os.Chmod(path, 0o600); err != nil {
return fmt.Errorf("private key %s is group/other accessible and chmod failed: %w", path, err)
}
}
return nil
} Try / catch
if runtime.GOOS != "windows" {
if fileInfo.Mode()&nonOwnerReadWriteMask != 0 {
return nil, fmt.Errorf("private key file %s must not be readable or writable by others", keyPath)
}
} Prevention
- Always create/copy private keys with chmod 600.
- Set umask 077 in environments that materialize key files.
- Avoid shared-group directories for private keys.
- When extracting keys from archives, re-tighten permissions before use.
When it happens
Trigger: Loading a private key file whose permissions include group read (mode ...04X), other read (...0X4), or any group/other write bit. Common after copying a key via a shared medium, extracting from a tarball that preserved loose perms, or creating it with a permissive umask.
Common situations: Key extracted from a zip/tar that set 0644; file created on a system with umask 022; key rsync'd with -p preserving group-readable perms; shared team directory where the file ended up group-readable; key downloaded from a secret manager with default perms.
Related errors
- failed to generate key for
- failed to write public key to
- refusing to load key from
- error importing key from
- warning: potential malicious behavior - trust data version…
AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07).
Data as JSON: /api/errors/2eda0c3f8e54a6ee.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/docker-trust/trust/key_load.go:80
keyBytes, err := getPrivKeyBytesFromPath(keyPath)
if err != nil {
return fmt.Errorf("refusing to load key from %s: %w", keyPath, err)
}
if err := loadPrivKeyBytesToStore(keyBytes, privKeyImporters, keyPath, options.keyName, passRet); err != nil {
return fmt.Errorf("error importing key from %s: %w", keyPath, err)
}
_, _ = fmt.Fprintln(streams.Out(), "Successfully imported key from", keyPath)
return nil
}
func getPrivKeyBytesFromPath(keyPath string) ([]byte, error) {
if runtime.GOOS != "windows" {
fileInfo, err := os.Stat(keyPath)
if err != nil {
return nil, err
}
if fileInfo.Mode()&nonOwnerReadWriteMask != 0 {
return nil, fmt.Errorf("private key file %s must not be readable or writable by others", keyPath)
}
}
from, err := os.OpenFile(keyPath, os.O_RDONLY, notary.PrivExecPerms)
if err != nil {
return nil, err
}
defer from.Close()
return io.ReadAll(from)
}
func loadPrivKeyBytesToStore(privKeyBytes []byte, privKeyImporters []trustmanager.Importer, keyPath, keyName string, passRet notary.PassRetriever) error {
var err error
if _, _, err = tufutils.ExtractPrivateKeyAttributes(privKeyBytes); err != nil {
return fmt.Errorf("provided file %s is not a supported private key - to add a signer's public key use docker trust signer add", keyPath)
}
if privKeyBytes, err = decodePrivKeyIfNecessary(privKeyBytes, passRet); err != nil {View on GitHub (pinned to 4f84911bfe)