{"record":{"id":"e310642f564ded39","repo":"docker/cli","slug":"error-remote-repository-s-out-of-date-v","errorCode":null,"errorMessage":"error: remote repository %s out-of-date: %v","messagePattern":"error: remote repository (.+?) out-of-date: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/docker-trust/internal/trust/trust.go","lineNumber":238,"sourceCode":"\t\tif v := env[alias]; v != \"\" {\n\t\t\treturn v, numAttempts > 1, nil\n\t\t}\n\t\t// For non-root roles, we can also try the \"default\" alias if it is specified\n\t\tif v := env[\"default\"]; v != \"\" && alias != data.CanonicalRootRole.String() {\n\t\t\treturn v, numAttempts > 1, nil\n\t\t}\n\t\treturn baseRetriever(keyName, alias, createNew, numAttempts)\n\t}\n}\n\n// NotaryError formats an error message received from the notary service\nfunc NotaryError(repoName string, err error) error {\n\tswitch err.(type) {\n\tcase *json.SyntaxError:\n\t\tlogrus.Debugf(\"Notary syntax error: %s\", err)\n\t\treturn fmt.Errorf(\"error: no trust data available for remote repository %s. Try running notary server and setting DOCKER_CONTENT_TRUST_SERVER to its HTTPS address\", repoName)\n\tcase signed.ErrExpired:\n\t\treturn fmt.Errorf(\"error: remote repository %s out-of-date: %v\", repoName, err)\n\tcase trustmanager.ErrKeyNotFound:\n\t\treturn fmt.Errorf(\"error: signing keys for remote repository %s not found: %v\", repoName, err)\n\tcase storage.NetworkError:\n\t\treturn fmt.Errorf(\"error: error contacting notary server: %v\", err)\n\tcase storage.ErrMetaNotFound:\n\t\treturn fmt.Errorf(\"error: trust data missing for remote repository %s or remote repository not found: %v\", repoName, err)\n\tcase trustpinning.ErrRootRotationFail, trustpinning.ErrValidationFail, signed.ErrInvalidKeyType:\n\t\treturn fmt.Errorf(\"warning: potential malicious behavior - trust data mismatch for remote repository %s: %v\", repoName, err)\n\tcase signed.ErrNoKeys:\n\t\treturn fmt.Errorf(\"error: could not find signing keys for remote repository %s, or could not decrypt signing key: %v\", repoName, err)\n\tcase signed.ErrLowVersion:\n\t\treturn fmt.Errorf(\"warning: potential malicious behavior - trust data version is lower than expected for remote repository %s: %v\", repoName, err)\n\tcase signed.ErrRoleThreshold:\n\t\treturn fmt.Errorf(\"warning: potential malicious behavior - trust data has insufficient signatures for remote repository %s: %v\", repoName, err)\n\tcase client.ErrRepositoryNotExist:\n\t\treturn fmt.Errorf(\"error: remote trust data does not exist for %s: %v\", repoName, err)\n\tcase signed.ErrInsufficientSignatures:\n\t\treturn fmt.Errorf(\"error: could not produce valid signature for %s.  If Yubikey was used, was touch input provided?: %v\", repoName, err)","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cmd/docker-trust/internal/trust/trust.go#L220-L256","documentation":"Returned by NotaryError (trust.go:238) when the notary error is signed.ErrExpired — TUF metadata (timestamps/snapshots) has expired, so the remote repository's trust data is considered out-of-date. TUF relies on time-bounded metadata to prevent freeze attacks; expired metadata must be refreshed by re-signing/re-publishing.","triggerScenarios":"The repository's timestamp or snapshot role metadata on the Notary server has passed its expiration (e.g. timestamp keys not rotating, snapshot not re-signed). A trusted pull/push validates metadata timestamps, sees they expired, and raises ErrExpired which NotaryError maps here.","commonSituations":"A Notary server that stopped publishing snapshot/timestamp updates (the automated signer offline), clock skew between client and server, or a repository left un-touched longer than the role's expiry threshold.","solutions":["Re-publish the repository metadata from a signer that holds the snapshot/timestamp keys (`docker trust signer add` then re-push, or notary CLI publish).","Ensure the Notary signer service is running and rotating timestamps automatically.","Check for client clock skew (`date`) and sync with NTP.","As a last resort rotate the expired keys and re-initialize trust for the repo."],"exampleFix":"# before: pulling against expired timestamp metadata\nDOCKER_CONTENT_TRUST=1 docker pull example.com/app:latest\n\n# after: refresh metadata on the signer side, then pull\nnotary publish example.com/app --server https://notary.example.com\nDOCKER_CONTENT_TRUST=1 docker pull example.com/app:latest","handlingStrategy":"retry","validationCode":"// Detect client clock skew that would falsely trip expiry\nif skew := ntpSkew(); skew > 5*time.Minute {\n    return fmt.Errorf(\"clock skew %s; sync NTP before trust operations\", skew)\n}","typeGuard":null,"tryCatchPattern":"// Refresh expired metadata then retry once\nif errors.Is(err, signed.ErrExpired) {\n    if rerr := republishMetadata(repo); rerr == nil {\n        err = trustedOp(repo)\n    }\n}","preventionTips":["Keep the Notary signer running so timestamp/snapshot metadata stays fresh.","Sync system clocks via NTP.","Monitor role expiry thresholds and rotate keys proactively."],"tags":["trust","notary","security","metadata-expiry"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}